Commit Graph

8017 Commits

Author SHA1 Message Date
H Hartley Sweeten
d0445303f8 staging: comedi: adv_pci1710: fix counter 0 internal clock source
There are a number of descrepencies in the various manuals for the boards
that this driver supports. Some show a 10 MHz clock for counters 1 and 2
others show a 1 MHz clock. Counter 0 can use either a div 10 of that clock
or an external clock (up to 10 MHz).

Currently this driver initializes counters 1 and 2 with a 10 MHz clock.
For consistency, return 1 MHz (10 MHz/10) for counter 0 when the user
queries the internal clock source with INSN_CONFIG_GET_CLOCK_SRC.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-12-18 14:56:30 -08:00
H Hartley Sweeten
0c917a9365 staging: comedi: adv_pci1710: tidy up pci1710_reset()
Change the return type to void, this function always succeeds and the
caller does not check the return value anyway.

Fix the initial programming of the control register. The SW bit enables
the software trigger and should not be set here. Setting CNT0 selects the
external clock source for counter 0 (the user counter). It makes more
sense to select the internal 1 MHz clock.

Remove the unnecessary initialization of the private data members. This
function is only called during the (*auto_attach) after the private
data was kzalloc'ed.

Remove the redundant clearing of the A/D FIFO and pending interrupts.
Just do it once.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-12-18 14:56:30 -08:00
H Hartley Sweeten
adbc9ec7fe staging: comedi: adv_pci1710: ai (*cancel) should not enable software trigger
The (*cancel) operation should do just that. Remove the setting of the SW bit
which enables the software trigger.

For aesthetics, rename the function so it has namespace associated with the
driver and add a couple comments.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-12-18 14:56:30 -08:00
H Hartley Sweeten
d3e8ab48db staging: comedi: adv_pci1710: post increment 'subdev' in (*auto_attach)
For aesthetics, post-increment the 'subdev' index when used to get a
comedi_subdevice pointer instead of incrementing it after the subdevice
is initialized.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-12-18 14:56:30 -08:00
H Hartley Sweeten
7387332558 staging: comedi: adv_pci1710: tidy up analog input subdev_flags
Remove the SDF_COMMON flag, the analog reference is not programmable and
the default aref (AREF_GROUND -> SDF_GROUND) provides adequate information
about the reference.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-12-18 14:56:30 -08:00
H Hartley Sweeten
1ef6e0a48e staging: comedi: adv_pci1710: tidy up analog output subdev_flags
Remove the SDF_COMMON flag, the analog reference is not programmable and
the default aref (AREF_GROUND -> SDF_GROUND) provides adequate information
about the reference.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-12-18 14:56:30 -08:00
H Hartley Sweeten
976e893b61 staging: comedi: adv_pci1710: support external analog output reference
The analog outputs can use an external reference to create the D/A output
range. Add an entry to the comedi_lrange table for it and modify the
(*insn_write) to support it.

Note that the D/A output range is 0 to +Vref with a -Vref. The comedi_lrange
does not include the sign of the range. It simmply allows the user to convert
between the 12-bit samples values (0x0000 - 0x0fff) and a physical value (0.0
to 1.0) using the comedilib comedi_to_phys() and comedi_from_phys() functions.
A physical value of 0.0 would actually be 0V with a -Vref and -V with a +Vref
and 1.0 would be +V with a -Vref and 0V with a -Vref. Ths user will need to
work this out but at least they can now use the external reference.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-12-18 14:56:30 -08:00
H Hartley Sweeten
baacf6ca54 staging: comedi: adv_pci1710: rename pci171x_ao_insn_write()
Rename this function so it has namespace associated with the driver.

For aesthetics, move the function so it is located in the middle of
the analog input support functions.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-12-18 14:56:30 -08:00
H Hartley Sweeten
6039278668 staging: comedi: adv_pci1710: rename pci171x_d[io]_insn_bits
Rename these functions so they have namespace associated with the driver.

For aesthetics, move the functions so they are not located in the middle
of the analog input/output support functions.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-12-18 14:56:30 -08:00
H Hartley Sweeten
f1f4ce6462 staging: comedi: adv_pci1710: rename pci171x_insn_counter_config()
Rename this function so it has namespace associated with the driver.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-12-18 14:56:30 -08:00
H Hartley Sweeten
96d57c15ab staging: comedi: adv_pci1710: rename interrupt_service_pci1710()
Rename this function so it has namespace associated with the driver.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-12-18 14:56:30 -08:00
H Hartley Sweeten
b5b147dcb4 staging: comedi: adv_pci1710: tidy up boardinfo definition
Remove the unnecessary comments and rename the 'rangelist_ai' member for
aesthetics.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-12-18 14:56:30 -08:00
H Hartley Sweeten
dbdb624822 staging: comedi: adv_pci1710: remove 'has_large_fifo' and 'has_diff_ai' boardinfo
The pci1711/31 boards are the only ones that have a smaller FIFO (1K vs 4K) and
single-ended analog inputs (no differential).

Replace the 'has_large_fifo' and 'has_diff_ai' members of the boardinfo with
'is_pci1711' and use that to determine how to initialize the analog input
subdev_flags as well as the private data 'max_samples'.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-12-18 14:56:30 -08:00
H Hartley Sweeten
88601533ae staging: comedi: adv_pci1710: remove 'has_di_do' boardinfo
This member of the boardinfo isn't really necessary. All the boards
except the pci1713 have 16 digital inputs and 16 digital outputs.

There is already a 'is_pci1713' member in the boardinfo so that can
be used to determine the subdevices for the digital inputs and outputs
need to be allocated and initialized.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-12-18 14:56:30 -08:00
H Hartley Sweeten
0b458e7304 staging: comedi: adv_pci1710: remove 'n_aichan' boardinfo
This member of the boardinfo isn't really necessary. All the boards
have analog inputs, the pci1713 has 32 channels the rest have 16
channels.

There is already a 'is_pci1713' member in the boardinfo so that can
be used to determine the number of channels for the analog input
subdevice.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-12-18 14:56:30 -08:00
H Hartley Sweeten
92c65e5553 staging: comedi: adv_pci1710: define the mux control register bits
For aesthetics, define some macros to set the bits in the mux control
register. Also, rename the 'mux_ext' member of the private data.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-12-18 14:56:30 -08:00
H Hartley Sweeten
7603900fc7 staging: comedi: adv_pci1710: refactor ai range programming
The gain codes used to program the analog output range are currently
stored in const char arrays. The values look a bit "magic" and it's
not clear how they associate with the comedi_lrange without looking
through user manuals.

Refactor the ai range programming to clarify the driver and remove
the magic numbers. Also, refine the bits in the range register that
set the differential and unipolar modes.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-12-18 14:56:30 -08:00
H Hartley Sweeten
19cbb8fb79 staging: comedi: adv_pci1710: don't "reset" board when detaching
Currently this driver calls pci1710_reset() during the (*detach) of
the driver. That function does the following:

  1) program the control register to stop any operations
  2) clears the analog input FIFO
  3) clears any pending interrupts
  4) sets all the analog output channels to unipolar 5V range and 0V output
  5) sets all the digital outputs to 0V

Before detaching the comedi core will (*cancel) any running async commands.
This will handle 1-3 above.

Depending on the application, it might not be safe to reset the analog and
digital outputs when the driver is detached.

Remove the board reset when detaching and just use comedi_pci_detach()
directly for the driver (*detach).

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-12-18 14:56:30 -08:00
H Hartley Sweeten
8a8d0875a5 staging: comedi: adv_pci1710: remove 'has_counter' boardinfo
All the boards supported by this driver have a 8254 counter. Channels
1 and 2 are used to create the cascaded 32-bit analog input pacer.
Counter 0 is available for the user on all the boards except the PCI-1713.

Remove the 'has_counter' boardinfo and use the 'is_pci1713' boardinfo to
determine if the user counter subdevice needs to be allocated and
initialized.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-12-18 14:56:30 -08:00
H Hartley Sweeten
6fa60dd4a4 staging: comedi: adv_pci1710: remove 'has_irq' boardinfo
All the boards supported by this driver can use an interrupt. Remove
the unnecessary boardinfo.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-12-18 14:56:30 -08:00
H Hartley Sweeten
14b93bb6bb staging: comedi: adv_pci_dio: separate out PCI-1760 support
The PCI-1760 is board unique. It uses an outgoing/incoming mailbox
programming sequence to access the hardware. The other boards supported
by this driver use simple register mapping. Including support for the
PCI-1760 in this driver just makes it harder to understand.

Separate out the PCI-1760 support into a new driver, adv_pci1760.

Clean up the new driver. The original code had a bunch of CamelCase and
other checkpatch.pl issues.

The code used to access the outgoing/incoming mailboxes was also a bit
awkward with the passing of the arrays for the outgoing and incoming
mailbox bytes. Replace them with two new functions that send a command
and return the feedback data from the command based on the programming
flow chart in the datasheet for the PCI-1760.

The new adv_pci1760 driver also fixes the incomplete timer subdevice.
This subdevice is actually the 2 PWM outputs so the subdevice type
has been changed to COMEDI_SUBD_PWM.

The counter subdevice support was not complete in the original code.
They are also a bit strange since they are up counters connected to
each of the digital inputs. For now that subdevice has been disabled
(COMEDI_SUBD_UNUSED).

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-12-18 14:54:24 -08:00
H Hartley Sweeten
b2cb068604 staging: comedi: adv_pci1710: separate out PCI-1720 support as a new driver
The PCI-1710 series boards are multifunction data acquisition boards with
analog inputs and outputs, digital inputs and outputs, and counter/timer
functions.

The PCI-1720 is a simple 4 channel analog output board. It also uses a
unique register map.

Separate out the PCI-1720 support as a new driver, adv_pci1720, to ease
maintainability.

Fix some issues with the PCI-1720 support in the new driver:
  1) the registers are all 8-bit
  2) remove the analog output "reset" when the driver attaches/detaches
  3) disable "synchronized output" to simplify the analog outputs
  4) remove the need for the private data
  5) add support for the BoardID register to allow multiple cards

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-11-15 20:02:47 -08:00
Ksenija Stanojevic
2aadecb60a Staging: comedi: adl_pci9118: Fix endian sparse warning
Fix following sparse warning:
warning: cast to restricted __be16

data is pointer of type void and can be used to store any type of data.
barray and array have the same 16 bit offset.

Signed-off-by: Ksenija Stanojevic <ksenija.stanojevic@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-11-15 20:02:47 -08:00
Ksenija Stanojevic
212efdb1be Staging: comedi: ni_mio_common: Fix endian sparse warning
Fix following sparse warnings:
warning: cast to restricted __le32
warning: cast to restricted __le16
warning: incorrect type in assignment (different base types)
expected unsigned short [unsigned] [assigned] val
got restricted __le16 [usertype] <noident>

Data is pointer of type void and can be used to store any type of data.
In function ni_ai_munge:
barray and array have the same 16 bit offset.
blarray and larray have the same 32 bit offset.

Signed-off-by: Ksenija Stanojevic <ksenija.stanojevic@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-11-15 20:02:47 -08:00
Ksenija Stanojevic
90e6228a99 Staging: comedi: das16: Fix sparse endian warning
Fix following sparse warning:
warning: cast to restricted __le16

This change is safe because array is pointer of type void and can
be used to store any type of data, also offset of the array would
be the same since unsigned short and __le16 are both 16 bits in size.

Signed-off-by: Ksenija Stanojevic <ksenija.stanojevic@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-11-15 20:02:47 -08:00
Ian Abbott
0cf55bbef2 staging: comedi: comedi_test: implement commands on AO subdevice
Implement COMEDI asynchronous commands on the fake analog output
subdevice.  This is useful for testing asynchronous commands in the
"write" direction when no real hardware is available.

A normal kernel timer is used to drive the command.  The new timer
expiry function `waveform_ao_timer()` handles whole "scans" at a time
according to the number of scan period that have elapsed since the last
scan.  Data for each channel in the scan is written to the internal
loopback array `devpriv->ao_loopbacks[]` and can be read back on the
analog input channels.  However, if several scan periods are outstanding
in the timer expiry function, only the latest available scan data is
written to the loopback array in order to save processing time.  The
expiry function also checks for underrun conditions, and checks for
normal termination of the asynchronous command when a "stop" scan count
is reached.

After the command is tested by `waveform_ao_cmdtest()` and set up by
`waveform_ao_cmd()`, it is not started until an internal trigger
function `waveform_ao_inttrig_start()` is called as a result of the user
performing an `INSN_INTTRIG` instruction on the subdevice.  The command
is stopped when the "cancel" handler `waveform_ao_cancel()` is called.
This may be due to the command terminating due to completion or an
error, or as a result of the user cancelling the command.

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-10-29 08:58:36 +09:00
Ian Abbott
9406a3140a staging: comedi: comedi_test: rename waveform_ai_interrupt()
`waveform_ai_interrupt()` is a timer expiry function used to generate
fake waveform data for an analog input subdevice.  Rename it to
`waveform_ai_timer()`.

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-10-29 08:58:36 +09:00
Ian Abbott
1eb85ae857 staging: comedi: comedi_test: handle partial scans in timer routine
For asynchronous command handling on the analog input subdevice, a
kernel timer routine is used to generate the fake waveform data.  A
"scan" consists of a number of conversions separated in time by a
conversion period.  Successive scans are separated in time by a scan
period, which is at least the conversion period multiplied by the number
of conversions per scan.  Currently, the timer routine does not generate
any data until the end of a scan period, generating whole scans of data
at a time.  Change it to generate data at the end of each conversion
period, with an extra delay after the final conversion in each scan if
necessary.  Use new member `ai_convert_time` in the private data
structure `struct waveform_private` to keep track of when the next
conversion is due.  This replaces the old member `ai_last_scan_time`
which kept track of the time of the previous scan.

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-10-29 08:58:36 +09:00
Ian Abbott
e0c6fe1294 staging: comedi: comedi_test: allow read-back of AO channels
COMEDI drivers often allow the last value written to a channel on an
analog output subdevice to be read back via the "insn_read" handler.
The "comedi_test" driver does not currently support that.  It is a bit
special because it loops back the last values written to the channel on
the analog output subdevice to be read back via corresponding channels
on the analog input subdevice.  The "insn_read" handler for the analog
input subdevice is `waveform_ai_insn_read()`.  Set that as the
"insn_read" handler for the analog output subdevice as well.

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-10-29 08:58:36 +09:00
Ian Abbott
3b2468fe98 staging: comedi: comedi_test: use unsigned short for loopback values
The last sample values written to the AO subdevice channels by its
"insn_write" handler `waveform_ao_insn_write()` are stored in the member
array `ao_loopbacks[]` in the device private data `struct
waveform_private`.  They can be read back via the "insn_read" handler of
the AI subdevice `waveform_ai_insn_read()`.  As the stored sample values
are only 16 bits wide, change the type of the `ao_loopbacks[]` member to
`unsigned short` to save some space.

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-10-29 08:58:36 +09:00
Ian Abbott
4e5ffbf29c staging: comedi: comedi_test: make timer rate similar to scan rate
The asynchronous command handling for the analog input subdevice uses a
kernel timer which expires approximately `HZ` times a second.  However,
it only needs to do anything after each scan period.  Set the timer to
expire just after the next scan period.

Although the timer expiry function `waveform_ai_interrupt()` uses
precise time values to generate the fake waveforms used to generate the
data, those time values are constructed in a precise sequence, and do
not depend on the time the timer expiry function is actually called.  So
the timer expiry rate does not have to be very precise.

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-10-29 08:58:36 +09:00
Ian Abbott
f3f24dff89 staging: comedi: comedi_test: rename waveform members
Rename the members `struct waveform_private` associated with fake
waveform generation.  The affected members are `uvolt_amplitude` -->
`wf_amplitude` (the amplitude of the waveform), `usec_period` -->
`wf_period` (the period of the waveform), and `usec_current` -->
`wf_current` (the current time within a waveform period).

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-10-29 08:58:36 +09:00
Ian Abbott
807060a369 staging: comedi: comedi_test: rename members for AI commands
Rename the members of `struct waveform_private` that are used to handle
AI commands, apart from those members used to control fake waveform
generation.  The renames are `timer` --> `ai_timer`, `scan_period` -->
`ai_scan_period`, and `convert_period` --> `ai_convert_period`.

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-10-29 08:58:36 +09:00
Ian Abbott
66d4da800d staging: comedi: comedi_test: simplify time since last AI scan
The private data structure `struct waveform_private` currently uses
member `last` to remember the time of the last timer interrupt, and the
member `usec_remainder` to keep track of how far into a simulated scan
the interrupt occurred.  Replace these with a single new member
`ai_last_scan_time` that records the time of the last scan.  This
simplifies the calculation of the number of scans to simulate in the
timer routine, `waveform_ai_interrupt()`.

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-10-29 08:58:36 +09:00
Ian Abbott
21ec1bf734 staging: comedi: comedi_test: use unsigned int for waveform timing
Use `unsigned int` instead of `unsigned long` to hold the period of the
fake waveform generator and the current time within each waveform.  The
waveform period will be no more than `INT_MAX` and the current time
within the waveform (prior to the modulo operation to bring it actually
within the waveform period) will be no more than `INT_MAX + UINT_MAX /
1000`.

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-10-29 08:58:36 +09:00
Ian Abbott
8fa8a260d2 staging: comedi: comedi_test: move modulo operations for waveform
The fake waveform generator functions, `fake_sawtooth()` and
`fake_squarewave()`, called from `fake_waveform()`, have a
`current_time` parameter which is the time since the start of a waveform
period.  The parameter value may be greater than the waveform period so
they do a modulo operation to bring it into range.  Do the modulo
operations outside the functions in `waveform_ai_interrupt()` so that
the waveform generator functions always get a `current_time` parameter
less than the waveform period and do not have to do the modulo operation
themselves.  Also, only do the modulo operations when the time since the
start of a waveform exceeds the waveform period.  Usually, several
samples are produced in each waveform period and modulo operations are
typically more expensive than a simple comparison.

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-10-29 08:58:36 +09:00
Ian Abbott
783ddaebd3 staging: comedi: comedi_test: support scan_begin_src == TRIG_FOLLOW
It is quite common for COMEDI subdevices that support commands to
support setting `scan_begin_src` to `TRIG_FOLLOW`.  This means the next
scan begins once all conversions in the current scan are complete.
Support the following timing combinations for the AI subdevice:

  scan_begin_src == TRIG_TIMER && convert_src == TRIG_TIMER
  scan_begin_src == TRIG_TIMER && convert_src == TRIG_NOW
  scan_begin_src == TRIG_FOLLOW && convert_src == TRIG_TIMER

The actual scan period in microseconds is stored in the `scan_period`
member of the private data structure `struct waveform_private`.  An
`unsigned int` is still wide enough, because the conversion period is no
more than `UINT_MAX / 1000` microseconds and the number of conversions
is no more than 16 (`N_CHANS * 2`).

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-10-29 08:58:36 +09:00
Ian Abbott
5afdcad2f8 staging: comedi: comedi_test: limit maximum convert_arg
When testing the parameters for setting up an asynchronous command on
the AI subdevice, limit the maximum conversion period
(`cmd->convert_arg`) so that the number of conversions in a scan
(`cmd->scan_end_arg`, same as `cmd->chanlist_len`) multiplied by the
conversion period fits within an `unsigned int`, as that is used to
limit the minimum scan period (`cmd->scan_begin_arg`).

Also ensure rounding of the conversion period and scan period to the
nearest microsecond both fit in an `unsigned int`.  Do all this in stage
4 ("fix up any arguments") of the command testing.

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-10-29 08:58:36 +09:00
Ian Abbott
87f64803ca staging: comedi: comedi_test: remove nano_per_micro
The `static const int nano_per_micro` variable is set to 1000, the
number of nanoseconds in a microsecond.  Remove it and use the
`NSEC_PER_USEC` macro from <linux/time.h> instead.

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-10-29 08:58:36 +09:00
Ian Abbott
19e86985b0 staging: comedi: comedi_test: saturate fake waveform values
While an asynchronous command is running on the analog input subdevice,
fake waveform generators are connected to each channel to provide the
input voltages that are converted to sample value.  Channel 0 is
connected to a sawtooth generator, channel 1 is connected to a
squarewave generator, and the remaining channels are connected to a
flatline generator.  The non-flatline generators share the same
amplitude (in microvolts) and period (in microseconds) which are
configured when the COMEDI device is attached.  All waveforms are
centered around 0 microvolts and the non-flatline waveforms go between
-amplitude and +amplitude.

It is possible for the waveforms to swing outside the input range of the
channels to which they are connected.  When that happens, the sample
values resulting from simulated A-to-D conversion will wrap around due
to integer overflow.  Prevent that by clamping the sample values that
would go out of range.  This is closer to how a real hardware device
would behave (assuming the input voltage is not high enough to damage
the hardware!).

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-10-29 08:58:36 +09:00
Ian Abbott
cbad8cf426 staging: comedi: comedi_test: reformat multi-line comments
Use the preferred style for multi-line comments.

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-10-29 08:58:36 +09:00
Ian Abbott
92d354cbe9 staging: comedi: fix extreme case of comedi_nsamples_left()
`comedi_nsamples_left(s, nsamples)` returns the number of samples
remaining to complete an asynchronous command or the passed in
`nsamples`, whichever is lower.  However, it goes wrong in the extreme
case of setting the `nsamples` parameter to `UINT_MAX` when the number
of conversions per "scan" (`s->async->cmd.scan_end_arg`) is 1.  It uses
`comedi_nscans_remaining(s, nscans)` to determine the number of scans
remaining, or the parameter `nscans`, whichever is lower.  To determine
the parameter `nscans`, it divides `nsamples` by the number of
conversions per scan and adds 1.  The addition of 1 is to avoid setting
the parameter `nscans` to 0, as `comedi_nscans_remaining(s, nscans)`
treats that value specially.  However in the extreme case where
`nsamples` is `UINT_MAX` and the number of samples per scan is 1, the
addition of 1 to `nscans` overflows, producing the unwanted 0.

Fix it by refactoring new a function `__comedi_nscans_remaining(s,
nscans)` out of `comedi_nscans_remaining(s, nscans)`.  The new function
does everything except the special handling when `nscans` is 0.  Change
`comedi_nsamples_remaining()` to call the new function without adding 1
to `nscans` to avoid the overflow.

This overflow bug doesn't affect any of the current COMEDI drivers.  I
stumbled across it while changing to one of the drivers.

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-10-27 14:31:25 +09:00
H Hartley Sweeten
eb96c7fc24 staging: comedi: adl_pci9118: tidy up pci9118_ai_setup_dma()
For aesthetics, init the dmalen[01] local variables when they are declared.

Use a local variable, 'scan_bytes', for the (devpriv->ai_n_realscanlen << 1)
calculation. For aesthetics and clarification, use comedi_bytes_per_sample()
instead of the '<< 1' shift to calculate the value.

The local variable 'i' is badly named. Remove it and use a local variable
'tmp' where it is used.

When checking the DMA buffer lengths for non-neverending commands the
scan length calculation, (devpriv->ai_n_realscanlen << 1) * cmd->stop_arg,
could overflow. Use and unsigned long long local variable to hold the
calculation and avoid the overflow.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-10-24 19:17:13 -07:00
H Hartley Sweeten
45037a9569 staging: comedi: adl_pci9118: rename interrupt_*() functions
For aesthetics, rename these functions so it they namespace associated
with the driver.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-10-24 19:17:13 -07:00
H Hartley Sweeten
5c912f1f28 staging: comedi: adl_pci9118: rename move_block_from_dma()
Rename this function so it has namespace associated with the driver.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-10-24 19:17:13 -07:00
H Hartley Sweeten
9459ff2b6b staging: comedi: adl_pci9118: rename valid_samples_in_act_dma_buf()
Rename this function so it has namespace associated with the driver.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-10-24 19:17:13 -07:00
H Hartley Sweeten
ad1a9646b7 staging: comedi: adl_pci9118: rename interrupt_pci9118_ai_mode4_switch()
For aesthetics, remove "interrupt_" from this functions name to shorten
it a bit.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-10-24 19:17:13 -07:00
H Hartley Sweeten
dd2907c3e7 staging: comedi: adl_pci9118: remove PCI9118_CHANLEN
This define is only used to initialize the analog input sudevice
'len_chanlist'. Remove the define and just open code the value.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-10-24 19:17:13 -07:00
H Hartley Sweeten
766957f6f1 staging: comedi: adl_pci9118: remove unused defines
These defines are not used in the driver. Remove them.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-10-24 19:17:13 -07:00
H Hartley Sweeten
0f3cb85ac8 staging: comedi: adl_pci9118: tidy up check_channel_list()
Rename this function to give it namespace associated with the driver.

Currently this function is called by both the AI (*do_cmdtest) and the (*do_cmd)
functions. It really only needs to be called by the (*do_cmdtest) to validate
that the chanlist meets the requirements of the hardware. It's only called by
the (*do_cmd) to verify that the scan length is not to large after adding the
extra samples needed to satisfy the DMA.

Move the extra scan length check into the (*do_cmd) function and remove the
unnecessary parameters 'frontadd' and 'backadd'.

Tidy up the reset of the function.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2015-10-24 19:17:13 -07:00