Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6: (714 commits) Staging: sxg: slicoss: Specify the license for Sahara SXG and Slicoss drivers Staging: serqt_usb: fix build due to proc tty changes Staging: serqt_usb: fix checkpatch errors Staging: serqt_usb: add TODO file Staging: serqt_usb: Lindent the code Staging: add USB serial Quatech driver staging: document that the wifi staging drivers a bit better Staging: echo cleanup Staging: BUG to BUG_ON changes Staging: remove some pointless conditionals before kfree_skb() Staging: line6: fix build error, select SND_RAWMIDI Staging: line6: fix checkpatch errors in variax.c Staging: line6: fix checkpatch errors in toneport.c Staging: line6: fix checkpatch errors in pcm.c Staging: line6: fix checkpatch errors in midibuf.c Staging: line6: fix checkpatch errors in midi.c Staging: line6: fix checkpatch errors in dumprequest.c Staging: line6: fix checkpatch errors in driver.c Staging: line6: fix checkpatch errors in audio.c Staging: line6: fix checkpatch errors in pod.c ...
This commit is contained in:
commit
3516c6a8dc
|
@ -0,0 +1,70 @@
|
|||
POHMELFS: Parallel Optimized Host Message Exchange Layered File System.
|
||||
|
||||
Evgeniy Polyakov <zbr@ioremap.net>
|
||||
|
||||
Homepage: http://www.ioremap.net/projects/pohmelfs
|
||||
|
||||
POHMELFS first began as a network filesystem with coherent local data and
|
||||
metadata caches but is now evolving into a parallel distributed filesystem.
|
||||
|
||||
Main features of this FS include:
|
||||
* Locally coherent cache for data and metadata with (potentially) byte-range locks.
|
||||
Since all Linux filesystems lock the whole inode during writing, algorithm
|
||||
is very simple and does not use byte-ranges, although they are sent in
|
||||
locking messages.
|
||||
* Completely async processing of all events except creation of hard and symbolic
|
||||
links, and rename events.
|
||||
Object creation and data reading and writing are processed asynchronously.
|
||||
* Flexible object architecture optimized for network processing.
|
||||
Ability to create long paths to objects and remove arbitrarily huge
|
||||
directories with a single network command.
|
||||
(like removing the whole kernel tree via a single network command).
|
||||
* Very high performance.
|
||||
* Fast and scalable multithreaded userspace server. Being in userspace it works
|
||||
with any underlying filesystem and still is much faster than async in-kernel NFS one.
|
||||
* Client is able to switch between different servers (if one goes down, client
|
||||
automatically reconnects to second and so on).
|
||||
* Transactions support. Full failover for all operations.
|
||||
Resending transactions to different servers on timeout or error.
|
||||
* Read request (data read, directory listing, lookup requests) balancing between multiple servers.
|
||||
* Write requests are replicated to multiple servers and completed only when all of them are acked.
|
||||
* Ability to add and/or remove servers from the working set at run-time.
|
||||
* Strong authentification and possible data encryption in network channel.
|
||||
* Extended attributes support.
|
||||
|
||||
POHMELFS is based on transactions, which are potentially long-standing objects that live
|
||||
in the client's memory. Each transaction contains all the information needed to process a given
|
||||
command (or set of commands, which is frequently used during data writing: single transactions
|
||||
can contain creation and data writing commands). Transactions are committed by all the servers
|
||||
to which they are sent and, in case of failures, are eventually resent or dropped with an error.
|
||||
For example, reading will return an error if no servers are available.
|
||||
|
||||
POHMELFS uses a asynchronous approach to data processing. Courtesy of transactions, it is
|
||||
possible to detach replies from requests and, if the command requires data to be received, the
|
||||
caller sleeps waiting for it. Thus, it is possible to issue multiple read commands to different
|
||||
servers and async threads will pick up replies in parallel, find appropriate transactions in the
|
||||
system and put the data where it belongs (like the page or inode cache).
|
||||
|
||||
The main feature of POHMELFS is writeback data and the metadata cache.
|
||||
Only a few non-performance critical operations use the write-through cache and
|
||||
are synchronous: hard and symbolic link creation, and object rename. Creation,
|
||||
removal of objects and data writing are asynchronous and are sent to
|
||||
the server during system writeback. Only one writer at a time is allowed for any
|
||||
given inode, which is guarded by an appropriate locking protocol.
|
||||
Because of this feature, POHMELFS is extremely fast at metadata intensive
|
||||
workloads and can fully utilize the bandwidth to the servers when doing bulk
|
||||
data transfers.
|
||||
|
||||
POHMELFS clients operate with a working set of servers and are capable of balancing read-only
|
||||
operations (like lookups or directory listings) between them.
|
||||
Administrators can add or remove servers from the set at run-time via special commands (described
|
||||
in Documentation/pohmelfs/info.txt file). Writes are replicated to all servers.
|
||||
|
||||
POHMELFS is capable of full data channel encryption and/or strong crypto hashing.
|
||||
One can select any kernel supported cipher, encryption mode, hash type and operation mode
|
||||
(hmac or digest). It is also possible to use both or neither (default). Crypto configuration
|
||||
is checked during mount time and, if the server does not support it, appropriate capabilities
|
||||
will be disabled or mount will fail (if 'crypto_fail_unsupported' mount option is specified).
|
||||
Crypto performance heavily depends on the number of crypto threads, which asynchronously perform
|
||||
crypto operations and send the resulting data to server or submit it up the stack. This number
|
||||
can be controlled via a mount option.
|
|
@ -0,0 +1,86 @@
|
|||
POHMELFS usage information.
|
||||
|
||||
Mount options:
|
||||
idx=%u
|
||||
Each mountpoint is associated with a special index via this option.
|
||||
Administrator can add or remove servers from the given index, so all mounts,
|
||||
which were attached to it, are updated.
|
||||
Default it is 0.
|
||||
|
||||
trans_scan_timeout=%u
|
||||
This timeout, expressed in milliseconds, specifies time to scan transaction
|
||||
trees looking for stale requests, which have to be resent, or if number of
|
||||
retries exceed specified limit, dropped with error.
|
||||
Default is 5 seconds.
|
||||
|
||||
drop_scan_timeout=%u
|
||||
Internal timeout, expressed in milliseconds, which specifies how frequently
|
||||
inodes marked to be dropped are freed. It also specifies how frequently
|
||||
the system checks that servers have to be added or removed from current working set.
|
||||
Default is 1 second.
|
||||
|
||||
wait_on_page_timeout=%u
|
||||
Number of milliseconds to wait for reply from remote server for data reading command.
|
||||
If this timeout is exceeded, reading returns an error.
|
||||
Default is 5 seconds.
|
||||
|
||||
trans_retries=%u
|
||||
This is the number of times that a transaction will be resent to a server that did
|
||||
not answer for the last @trans_scan_timeout milliseconds.
|
||||
When the number of resends exceeds this limit, the transaction is completed with error.
|
||||
Default is 5 resends.
|
||||
|
||||
crypto_thread_num=%u
|
||||
Number of crypto processing threads. Threads are used both for RX and TX traffic.
|
||||
Default is 2, or no threads if crypto operations are not supported.
|
||||
|
||||
trans_max_pages=%u
|
||||
Maximum number of pages in a single transaction. This parameter also controls
|
||||
the number of pages, allocated for crypto processing (each crypto thread has
|
||||
pool of pages, the number of which is equal to 'trans_max_pages'.
|
||||
Default is 100 pages.
|
||||
|
||||
crypto_fail_unsupported
|
||||
If specified, mount will fail if the server does not support requested crypto operations.
|
||||
By default mount will disable non-matching crypto operations.
|
||||
|
||||
mcache_timeout=%u
|
||||
Maximum number of milliseconds to wait for the mcache objects to be processed.
|
||||
Mcache includes locks (given lock should be granted by server), attributes (they should be
|
||||
fully received in the given timeframe).
|
||||
Default is 5 seconds.
|
||||
|
||||
Usage examples.
|
||||
|
||||
Add (or remove if it already exists) server server1.net:1025 into the working set with index $idx
|
||||
with appropriate hash algorithm and key file and cipher algorithm, mode and key file:
|
||||
$cfg -a server1.net -p 1025 -i $idx -K $hash_key -k $cipher_key
|
||||
|
||||
Mount filesystem with given index $idx to /mnt mountpoint.
|
||||
Client will connect to all servers specified in the working set via previous command:
|
||||
mount -t pohmel -o idx=$idx q /mnt
|
||||
|
||||
One can add or remove servers from working set after mounting too.
|
||||
|
||||
|
||||
Server installation.
|
||||
|
||||
Creating a server, which listens at port 1025 and 0.0.0.0 address.
|
||||
Working root directory (note, that server chroots there, so you have to have appropriate permissions)
|
||||
is set to /mnt, server will negotiate hash/cipher with client, in case client requested it, there
|
||||
are appropriate key files.
|
||||
Number of working threads is set to 10.
|
||||
|
||||
# ./fserver -a 0.0.0.0 -p 1025 -r /mnt -w 10 -K hash_key -k cipher_key
|
||||
|
||||
-A 6 - listen on ipv6 address. Default: Disabled.
|
||||
-r root - path to root directory. Default: /tmp.
|
||||
-a addr - listen address. Default: 0.0.0.0.
|
||||
-p port - listen port. Default: 1025.
|
||||
-w workers - number of workers per connected client. Default: 1.
|
||||
-K file - hash key size. Default: none.
|
||||
-k file - cipher key size. Default: none.
|
||||
-h - this help.
|
||||
|
||||
Number of worker threads specifies how many workers will be created for each client.
|
||||
Bulk single-client transafers usually are better handled with smaller number (like 1-3).
|
|
@ -0,0 +1,227 @@
|
|||
POHMELFS network protocol.
|
||||
|
||||
Basic structure used in network communication is following command:
|
||||
|
||||
struct netfs_cmd
|
||||
{
|
||||
__u16 cmd; /* Command number */
|
||||
__u16 csize; /* Attached crypto information size */
|
||||
__u16 cpad; /* Attached padding size */
|
||||
__u16 ext; /* External flags */
|
||||
__u32 size; /* Size of the attached data */
|
||||
__u32 trans; /* Transaction id */
|
||||
__u64 id; /* Object ID to operate on. Used for feedback.*/
|
||||
__u64 start; /* Start of the object. */
|
||||
__u64 iv; /* IV sequence */
|
||||
__u8 data[0];
|
||||
};
|
||||
|
||||
Commands can be embedded into transaction command (which in turn has own command),
|
||||
so one can extend protocol as needed without breaking backward compatibility as long
|
||||
as old commands are supported. All string lengths include tail 0 byte.
|
||||
|
||||
All commans are transfered over the network in big-endian. CPU endianess is used at the end peers.
|
||||
|
||||
@cmd - command number, which specifies command to be processed. Following
|
||||
commands are used currently:
|
||||
|
||||
NETFS_READDIR = 1, /* Read directory for given inode number */
|
||||
NETFS_READ_PAGE, /* Read data page from the server */
|
||||
NETFS_WRITE_PAGE, /* Write data page to the server */
|
||||
NETFS_CREATE, /* Create directory entry */
|
||||
NETFS_REMOVE, /* Remove directory entry */
|
||||
NETFS_LOOKUP, /* Lookup single object */
|
||||
NETFS_LINK, /* Create a link */
|
||||
NETFS_TRANS, /* Transaction */
|
||||
NETFS_OPEN, /* Open intent */
|
||||
NETFS_INODE_INFO, /* Metadata cache coherency synchronization message */
|
||||
NETFS_PAGE_CACHE, /* Page cache invalidation message */
|
||||
NETFS_READ_PAGES, /* Read multiple contiguous pages in one go */
|
||||
NETFS_RENAME, /* Rename object */
|
||||
NETFS_CAPABILITIES, /* Capabilities of the client, for example supported crypto */
|
||||
NETFS_LOCK, /* Distributed lock message */
|
||||
NETFS_XATTR_SET, /* Set extended attribute */
|
||||
NETFS_XATTR_GET, /* Get extended attribute */
|
||||
|
||||
@ext - external flags. Used by different commands to specify some extra arguments
|
||||
like partial size of the embedded objects or creation flags.
|
||||
|
||||
@size - size of the attached data. For NETFS_READ_PAGE and NETFS_READ_PAGES no data is attached,
|
||||
but size of the requested data is incorporated here. It does not include size of the command
|
||||
header (struct netfs_cmd) itself.
|
||||
|
||||
@id - id of the object this command operates on. Each command can use it for own purpose.
|
||||
|
||||
@start - start of the object this command operates on. Each command can use it for own purpose.
|
||||
|
||||
@csize, @cpad - size and padding size of the (attached if needed) crypto information.
|
||||
|
||||
Command specifications.
|
||||
|
||||
@NETFS_READDIR
|
||||
This command is used to sync content of the remote dir to the client.
|
||||
|
||||
@ext - length of the path to object.
|
||||
@size - the same.
|
||||
@id - local inode number of the directory to read.
|
||||
@start - zero.
|
||||
|
||||
|
||||
@NETFS_READ_PAGE
|
||||
This command is used to read data from remote server.
|
||||
Data size does not exceed local page cache size.
|
||||
|
||||
@id - inode number.
|
||||
@start - first byte offset.
|
||||
@size - number of bytes to read plus length of the path to object.
|
||||
@ext - object path length.
|
||||
|
||||
|
||||
@NETFS_CREATE
|
||||
Used to create object.
|
||||
It does not require that all directories on top of the object were
|
||||
already created, it will create them automatically. Each object has
|
||||
associated @netfs_path_entry data structure, which contains creation
|
||||
mode (permissions and type) and length of the name as long as name itself.
|
||||
|
||||
@start - 0
|
||||
@size - size of the all data structures needed to create a path
|
||||
@id - local inode number
|
||||
@ext - 0
|
||||
|
||||
|
||||
@NETFS_REMOVE
|
||||
Used to remove object.
|
||||
|
||||
@ext - length of the path to object.
|
||||
@size - the same.
|
||||
@id - local inode number.
|
||||
@start - zero.
|
||||
|
||||
|
||||
@NETFS_LOOKUP
|
||||
Lookup information about object on server.
|
||||
|
||||
@ext - length of the path to object.
|
||||
@size - the same.
|
||||
@id - local inode number of the directory to look object in.
|
||||
@start - local inode number of the object to look at.
|
||||
|
||||
|
||||
@NETFS_LINK
|
||||
Create hard of symlink.
|
||||
Command is sent as "object_path|target_path".
|
||||
|
||||
@size - size of the above string.
|
||||
@id - parent local inode number.
|
||||
@start - 1 for symlink, 0 for hardlink.
|
||||
@ext - size of the "object_path" above.
|
||||
|
||||
|
||||
@NETFS_TRANS
|
||||
Transaction header.
|
||||
|
||||
@size - incorporates all embedded command sizes including theirs header sizes.
|
||||
@start - transaction generation number - unique id used to find transaction.
|
||||
@ext - transaction flags. Unused at the moment.
|
||||
@id - 0.
|
||||
|
||||
|
||||
@NETFS_OPEN
|
||||
Open intent for given transaction.
|
||||
|
||||
@id - local inode number.
|
||||
@start - 0.
|
||||
@size - path length to the object.
|
||||
@ext - open flags (O_RDWR and so on).
|
||||
|
||||
|
||||
@NETFS_INODE_INFO
|
||||
Metadata update command.
|
||||
It is sent to servers when attributes of the object are changed and received
|
||||
when data or metadata were updated. It operates with the following structure:
|
||||
|
||||
struct netfs_inode_info
|
||||
{
|
||||
unsigned int mode;
|
||||
unsigned int nlink;
|
||||
unsigned int uid;
|
||||
unsigned int gid;
|
||||
unsigned int blocksize;
|
||||
unsigned int padding;
|
||||
__u64 ino;
|
||||
__u64 blocks;
|
||||
__u64 rdev;
|
||||
__u64 size;
|
||||
__u64 version;
|
||||
};
|
||||
|
||||
It effectively mirrors stat(2) returned data.
|
||||
|
||||
|
||||
@ext - path length to the object.
|
||||
@size - the same plus size of the netfs_inode_info structure.
|
||||
@id - local inode number.
|
||||
@start - 0.
|
||||
|
||||
|
||||
@NETFS_PAGE_CACHE
|
||||
Command is only received by clients. It contains information about
|
||||
page to be marked as not up-to-date.
|
||||
|
||||
@id - client's inode number.
|
||||
@start - last byte of the page to be invalidated. If it is not equal to
|
||||
current inode size, it will be vmtruncated().
|
||||
@size - 0
|
||||
@ext - 0
|
||||
|
||||
|
||||
@NETFS_READ_PAGES
|
||||
Used to read multiple contiguous pages in one go.
|
||||
|
||||
@start - first byte of the contiguous region to read.
|
||||
@size - contains of two fields: lower 8 bits are used to represent page cache shift
|
||||
used by client, another 3 bytes are used to get number of pages.
|
||||
@id - local inode number.
|
||||
@ext - path length to the object.
|
||||
|
||||
|
||||
@NETFS_RENAME
|
||||
Used to rename object.
|
||||
Attached data is formed into following string: "old_path|new_path".
|
||||
|
||||
@id - local inode number.
|
||||
@start - parent inode number.
|
||||
@size - length of the above string.
|
||||
@ext - length of the old path part.
|
||||
|
||||
|
||||
@NETFS_CAPABILITIES
|
||||
Used to exchange crypto capabilities with server.
|
||||
If crypto capabilities are not supported by server, then client will disable it
|
||||
or fail (if 'crypto_fail_unsupported' mount options was specified).
|
||||
|
||||
@id - superblock index. Used to specify crypto information for group of servers.
|
||||
@size - size of the attached capabilities structure.
|
||||
@start - 0.
|
||||
@size - 0.
|
||||
@scsize - 0.
|
||||
|
||||
@NETFS_LOCK
|
||||
Used to send lock request/release messages. Although it sends byte range request
|
||||
and is capable of flushing pages based on that, it is not used, since all Linux
|
||||
filesystems lock the whole inode.
|
||||
|
||||
@id - lock generation number.
|
||||
@start - start of the locked range.
|
||||
@size - size of the locked range.
|
||||
@ext - lock type: read/write. Not used actually. 15'th bit is used to determine,
|
||||
if it is lock request (1) or release (0).
|
||||
|
||||
@NETFS_XATTR_SET
|
||||
@NETFS_XATTR_GET
|
||||
Used to set/get extended attributes for given inode.
|
||||
@id - attribute generation number or xattr setting type
|
||||
@start - size of the attribute (request or attached)
|
||||
@size - name length, path len and data size for given attribute
|
||||
@ext - path length for given object
|
|
@ -73,6 +73,8 @@ source "drivers/staging/rt2860/Kconfig"
|
|||
|
||||
source "drivers/staging/rt2870/Kconfig"
|
||||
|
||||
source "drivers/staging/rt3070/Kconfig"
|
||||
|
||||
source "drivers/staging/comedi/Kconfig"
|
||||
|
||||
source "drivers/staging/asus_oled/Kconfig"
|
||||
|
@ -93,5 +95,25 @@ source "drivers/staging/epl/Kconfig"
|
|||
|
||||
source "drivers/staging/android/Kconfig"
|
||||
|
||||
source "drivers/staging/dst/Kconfig"
|
||||
|
||||
source "drivers/staging/pohmelfs/Kconfig"
|
||||
|
||||
source "drivers/staging/stlc45xx/Kconfig"
|
||||
|
||||
source "drivers/staging/uc2322/Kconfig"
|
||||
|
||||
source "drivers/staging/b3dfg/Kconfig"
|
||||
|
||||
source "drivers/staging/phison/Kconfig"
|
||||
|
||||
source "drivers/staging/p9auth/Kconfig"
|
||||
|
||||
source "drivers/staging/heci/Kconfig"
|
||||
|
||||
source "drivers/staging/line6/Kconfig"
|
||||
|
||||
source "drivers/staging/serqt_usb/Kconfig"
|
||||
|
||||
endif # !STAGING_EXCLUDE_BUILD
|
||||
endif # STAGING
|
||||
|
|
|
@ -19,6 +19,7 @@ obj-$(CONFIG_AGNX) += agnx/
|
|||
obj-$(CONFIG_OTUS) += otus/
|
||||
obj-$(CONFIG_RT2860) += rt2860/
|
||||
obj-$(CONFIG_RT2870) += rt2870/
|
||||
obj-$(CONFIG_RT3070) += rt3070/
|
||||
obj-$(CONFIG_COMEDI) += comedi/
|
||||
obj-$(CONFIG_ASUS_OLED) += asus_oled/
|
||||
obj-$(CONFIG_PANEL) += panel/
|
||||
|
@ -29,3 +30,13 @@ obj-$(CONFIG_INPUT_MIMIO) += mimio/
|
|||
obj-$(CONFIG_TRANZPORT) += frontier/
|
||||
obj-$(CONFIG_EPL) += epl/
|
||||
obj-$(CONFIG_ANDROID) += android/
|
||||
obj-$(CONFIG_DST) += dst/
|
||||
obj-$(CONFIG_POHMELFS) += pohmelfs/
|
||||
obj-$(CONFIG_STLC45XX) += stlc45xx/
|
||||
obj-$(CONFIG_USB_SERIAL_ATEN2011) += uc2322/
|
||||
obj-$(CONFIG_B3DFG) += b3dfg/
|
||||
obj-$(CONFIG_IDE_PHISON) += phison/
|
||||
obj-$(CONFIG_PLAN9AUTH) += p9auth/
|
||||
obj-$(CONFIG_HECI) += heci/
|
||||
obj-$(CONFIG_LINE6_USB) += line6/
|
||||
obj-$(CONFIG_USB_SERIAL_QUATECH_ESU100) += serqt_usb/
|
||||
|
|
|
@ -41,16 +41,16 @@ static const struct ieee80211_rate agnx_rates_80211g[] = {
|
|||
/* { .bitrate = 20, .hw_value = 2, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, */
|
||||
/* { .bitrate = 55, .hw_value = 3, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, */
|
||||
/* { .bitrate = 110, .hw_value = 4, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, */
|
||||
{ .bitrate = 10, .hw_value = 1, },
|
||||
{ .bitrate = 20, .hw_value = 2, },
|
||||
{ .bitrate = 55, .hw_value = 3, },
|
||||
{ .bitrate = 110, .hw_value = 4,},
|
||||
{ .bitrate = 10, .hw_value = 1, },
|
||||
{ .bitrate = 20, .hw_value = 2, },
|
||||
{ .bitrate = 55, .hw_value = 3, },
|
||||
{ .bitrate = 110, .hw_value = 4,},
|
||||
|
||||
{ .bitrate = 60, .hw_value = 0xB, },
|
||||
{ .bitrate = 90, .hw_value = 0xF, },
|
||||
{ .bitrate = 120, .hw_value = 0xA },
|
||||
{ .bitrate = 180, .hw_value = 0xE, },
|
||||
// { .bitrate = 240, .hw_value = 0xd, },
|
||||
/* { .bitrate = 240, .hw_value = 0xd, }, */
|
||||
{ .bitrate = 360, .hw_value = 0xD, },
|
||||
{ .bitrate = 480, .hw_value = 0x8, },
|
||||
{ .bitrate = 540, .hw_value = 0xC, },
|
||||
|
@ -110,10 +110,10 @@ struct agnx_priv {
|
|||
/* Need volatile? */
|
||||
u32 irq_status;
|
||||
|
||||
struct delayed_work periodic_work; /* Periodic tasks like recalibrate*/
|
||||
struct delayed_work periodic_work; /* Periodic tasks like recalibrate */
|
||||
struct ieee80211_low_level_stats stats;
|
||||
|
||||
// unsigned int phymode;
|
||||
/* unsigned int phymode; */
|
||||
int mode;
|
||||
int channel;
|
||||
u8 bssid[ETH_ALEN];
|
||||
|
|
|
@ -23,7 +23,7 @@ static inline void agnx_bug(char *reason)
|
|||
|
||||
static inline void agnx_print_desc(struct agnx_desc *desc)
|
||||
{
|
||||
u32 reg = be32_to_cpu(desc->frag);
|
||||
u32 reg = be32_to_cpu(desc->frag);
|
||||
|
||||
PRINTK_BITS(DESC, PACKET_LEN);
|
||||
|
||||
|
@ -291,7 +291,7 @@ static inline void agnx_print_sta(struct agnx_priv *priv, unsigned int sta_idx)
|
|||
PRINTK_LE32(STA, sta->phy_stats_high);
|
||||
PRINTK_LE32(STA, sta->phy_stats_low);
|
||||
|
||||
// for (i = 0; i < 8; i++)
|
||||
/* for (i = 0; i < 8; i++) */
|
||||
agnx_print_sta_traffic(sta->traffic + 0);
|
||||
|
||||
PRINTK_LE16(STA, sta->traffic_class0_frag_success);
|
||||
|
@ -311,10 +311,10 @@ static inline void agnx_print_sta(struct agnx_priv *priv, unsigned int sta_idx)
|
|||
static inline void dump_ieee80211_hdr(struct ieee80211_hdr *hdr, char *tag)
|
||||
{
|
||||
u16 fctl;
|
||||
int hdrlen;
|
||||
int hdrlen;
|
||||
DECLARE_MAC_BUF(mac);
|
||||
|
||||
fctl = le16_to_cpu(hdr->frame_control);
|
||||
fctl = le16_to_cpu(hdr->frame_control);
|
||||
switch (fctl & IEEE80211_FCTL_FTYPE) {
|
||||
case IEEE80211_FTYPE_DATA:
|
||||
printk(PFX "%s DATA ", tag);
|
||||
|
@ -324,7 +324,7 @@ static inline void dump_ieee80211_hdr(struct ieee80211_hdr *hdr, char *tag)
|
|||
break;
|
||||
case IEEE80211_FTYPE_MGMT:
|
||||
printk(PFX "%s MGMT ", tag);
|
||||
switch(fctl & IEEE80211_FCTL_STYPE) {
|
||||
switch (fctl & IEEE80211_FCTL_STYPE) {
|
||||
case IEEE80211_STYPE_ASSOC_REQ:
|
||||
printk("SubType: ASSOC_REQ ");
|
||||
break;
|
||||
|
@ -369,7 +369,7 @@ static inline void dump_ieee80211_hdr(struct ieee80211_hdr *hdr, char *tag)
|
|||
printk(PFX "%s Packet type: Unknow\n", tag);
|
||||
}
|
||||
|
||||
hdrlen = ieee80211_hdrlen(fctl);
|
||||
hdrlen = ieee80211_hdrlen(fctl);
|
||||
|
||||
if (hdrlen >= 4)
|
||||
printk("FC=0x%04x DUR=0x%04x",
|
||||
|
@ -389,29 +389,28 @@ static inline void dump_txm_registers(struct agnx_priv *priv)
|
|||
{
|
||||
void __iomem *ctl = priv->ctl;
|
||||
int i;
|
||||
for (i = 0; i <=0x1e8; i += 4) {
|
||||
for (i = 0; i <= 0x1e8; i += 4)
|
||||
printk(KERN_DEBUG PFX "TXM: %x---> 0x%.8x\n", i, ioread32(ctl + i));
|
||||
}
|
||||
}
|
||||
static inline void dump_rxm_registers(struct agnx_priv *priv)
|
||||
{
|
||||
void __iomem *ctl = priv->ctl;
|
||||
int i;
|
||||
for (i = 0; i <=0x108; i += 4)
|
||||
for (i = 0; i <= 0x108; i += 4)
|
||||
printk(KERN_DEBUG PFX "RXM: %x---> 0x%.8x\n", i, ioread32(ctl + 0x2000 + i));
|
||||
}
|
||||
static inline void dump_bm_registers(struct agnx_priv *priv)
|
||||
{
|
||||
void __iomem *ctl = priv->ctl;
|
||||
int i;
|
||||
for (i = 0; i <=0x90; i += 4)
|
||||
for (i = 0; i <= 0x90; i += 4)
|
||||
printk(KERN_DEBUG PFX "BM: %x---> 0x%.8x\n", i, ioread32(ctl + 0x2c00 + i));
|
||||
}
|
||||
static inline void dump_cir_registers(struct agnx_priv *priv)
|
||||
{
|
||||
void __iomem *ctl = priv->ctl;
|
||||
int i;
|
||||
for (i = 0; i <=0xb8; i += 4)
|
||||
for (i = 0; i <= 0xb8; i += 4)
|
||||
printk(KERN_DEBUG PFX "CIR: %x---> 0x%.8x\n", i, ioread32(ctl + 0x3000 + i));
|
||||
}
|
||||
|
||||
|
|
|
@ -39,34 +39,34 @@ static inline void agnx_interrupt_ack(struct agnx_priv *priv, u32 *reason)
|
|||
void __iomem *ctl = priv->ctl;
|
||||
u32 reg;
|
||||
|
||||
if ( *reason & AGNX_STAT_RX ) {
|
||||
if (*reason & AGNX_STAT_RX) {
|
||||
/* Mark complete RX */
|
||||
reg = ioread32(ctl + AGNX_CIR_RXCTL);
|
||||
reg |= 0x4;
|
||||
iowrite32(reg, ctl + AGNX_CIR_RXCTL);
|
||||
/* disable Rx interrupt */
|
||||
}
|
||||
if ( *reason & AGNX_STAT_TX ) {
|
||||
if (*reason & AGNX_STAT_TX) {
|
||||
reg = ioread32(ctl + AGNX_CIR_TXDCTL);
|
||||
if (reg & 0x4) {
|
||||
iowrite32(reg, ctl + AGNX_CIR_TXDCTL);
|
||||
*reason |= AGNX_STAT_TXD;
|
||||
}
|
||||
reg = ioread32(ctl + AGNX_CIR_TXMCTL);
|
||||
reg = ioread32(ctl + AGNX_CIR_TXMCTL);
|
||||
if (reg & 0x4) {
|
||||
iowrite32(reg, ctl + AGNX_CIR_TXMCTL);
|
||||
*reason |= AGNX_STAT_TXM;
|
||||
}
|
||||
}
|
||||
if ( *reason & AGNX_STAT_X ) {
|
||||
/* reg = ioread32(ctl + AGNX_INT_STAT); */
|
||||
/* iowrite32(reg, ctl + AGNX_INT_STAT); */
|
||||
/* /\* FIXME reinit interrupt mask *\/ */
|
||||
/* reg = 0xc390bf9 & ~IRQ_TX_BEACON; */
|
||||
/* reg &= ~IRQ_TX_DISABLE; */
|
||||
/* iowrite32(reg, ctl + AGNX_INT_MASK); */
|
||||
/* iowrite32(0x800, ctl + AGNX_CIR_BLKCTL); */
|
||||
}
|
||||
/* if (*reason & AGNX_STAT_X) {
|
||||
reg = ioread32(ctl + AGNX_INT_STAT);
|
||||
iowrite32(reg, ctl + AGNX_INT_STAT);
|
||||
/* FIXME reinit interrupt mask *\/
|
||||
reg = 0xc390bf9 & ~IRQ_TX_BEACON;
|
||||
reg &= ~IRQ_TX_DISABLE;
|
||||
iowrite32(reg, ctl + AGNX_INT_MASK);
|
||||
iowrite32(0x800, ctl + AGNX_CIR_BLKCTL);
|
||||
} */
|
||||
} /* agnx_interrupt_ack */
|
||||
|
||||
static irqreturn_t agnx_interrupt_handler(int irq, void *dev_id)
|
||||
|
@ -79,7 +79,7 @@ static irqreturn_t agnx_interrupt_handler(int irq, void *dev_id)
|
|||
|
||||
spin_lock(&priv->lock);
|
||||
|
||||
// printk(KERN_ERR PFX "Get a interrupt %s\n", __func__);
|
||||
/* printk(KERN_ERR PFX "Get a interrupt %s\n", __func__); */
|
||||
|
||||
if (priv->init_status != AGNX_START)
|
||||
goto out;
|
||||
|
@ -92,7 +92,7 @@ static irqreturn_t agnx_interrupt_handler(int irq, void *dev_id)
|
|||
ret = IRQ_HANDLED;
|
||||
priv->irq_status = ioread32(ctl + AGNX_INT_STAT);
|
||||
|
||||
// printk(PFX "Interrupt reason is 0x%x\n", irq_reason);
|
||||
/* printk(PFX "Interrupt reason is 0x%x\n", irq_reason); */
|
||||
/* Make sure the txm and txd flags don't conflict with other unknown
|
||||
interrupt flag, maybe is not necessary */
|
||||
irq_reason &= 0xF;
|
||||
|
@ -101,13 +101,13 @@ static irqreturn_t agnx_interrupt_handler(int irq, void *dev_id)
|
|||
/* TODO Make sure the card finished initialized */
|
||||
agnx_interrupt_ack(priv, &irq_reason);
|
||||
|
||||
if ( irq_reason & AGNX_STAT_RX )
|
||||
if (irq_reason & AGNX_STAT_RX)
|
||||
handle_rx_irq(priv);
|
||||
if ( irq_reason & AGNX_STAT_TXD )
|
||||
if (irq_reason & AGNX_STAT_TXD)
|
||||
handle_txd_irq(priv);
|
||||
if ( irq_reason & AGNX_STAT_TXM )
|
||||
if (irq_reason & AGNX_STAT_TXM)
|
||||
handle_txm_irq(priv);
|
||||
if ( irq_reason & AGNX_STAT_X )
|
||||
if (irq_reason & AGNX_STAT_X)
|
||||
handle_other_irq(priv);
|
||||
|
||||
enable_rx_interrupt(priv);
|
||||
|
@ -171,7 +171,7 @@ static int agnx_alloc_rings(struct agnx_priv *priv)
|
|||
|
||||
len = priv->rx.size + priv->txm.size + priv->txd.size;
|
||||
|
||||
// priv->rx.info = kzalloc(sizeof(struct agnx_info) * len, GFP_KERNEL);
|
||||
/* priv->rx.info = kzalloc(sizeof(struct agnx_info) * len, GFP_KERNEL); */
|
||||
priv->rx.info = kzalloc(sizeof(struct agnx_info) * len, GFP_ATOMIC);
|
||||
if (!priv->rx.info)
|
||||
return -ENOMEM;
|
||||
|
@ -210,28 +210,27 @@ static void rings_free(struct agnx_priv *priv)
|
|||
#if 0
|
||||
static void agnx_periodic_work_handler(struct work_struct *work)
|
||||
{
|
||||
struct agnx_priv *priv = container_of(work, struct agnx_priv,
|
||||
periodic_work.work);
|
||||
// unsigned long flags;
|
||||
struct agnx_priv *priv = container_of(work, struct agnx_priv, periodic_work.work);
|
||||
/* unsigned long flags; */
|
||||
unsigned long delay;
|
||||
|
||||
/* fixme: using mutex?? */
|
||||
// spin_lock_irqsave(&priv->lock, flags);
|
||||
/* spin_lock_irqsave(&priv->lock, flags); */
|
||||
|
||||
/* TODO Recalibrate*/
|
||||
// calibrate_oscillator(priv);
|
||||
// antenna_calibrate(priv);
|
||||
// agnx_send_packet(priv, 997);
|
||||
/* calibrate_oscillator(priv); */
|
||||
/* antenna_calibrate(priv); */
|
||||
/* agnx_send_packet(priv, 997); /
|
||||
/* FIXME */
|
||||
/* if (debug == 3) */
|
||||
/* delay = msecs_to_jiffies(AGNX_PERIODIC_DELAY); */
|
||||
/* else */
|
||||
delay = msecs_to_jiffies(AGNX_PERIODIC_DELAY);
|
||||
// delay = round_jiffies(HZ * 15);
|
||||
/* delay = round_jiffies(HZ * 15); */
|
||||
|
||||
queue_delayed_work(priv->hw->workqueue, &priv->periodic_work, delay);
|
||||
|
||||
// spin_unlock_irqrestore(&priv->lock, flags);
|
||||
/* spin_unlock_irqrestore(&priv->lock, flags); */
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -255,12 +254,12 @@ static int agnx_start(struct ieee80211_hw *dev)
|
|||
goto out;
|
||||
}
|
||||
|
||||
// mdelay(500);
|
||||
/* mdelay(500); */
|
||||
|
||||
might_sleep();
|
||||
agnx_hw_init(priv);
|
||||
|
||||
// mdelay(500);
|
||||
/* mdelay(500); */
|
||||
might_sleep();
|
||||
|
||||
priv->init_status = AGNX_START;
|
||||
|
@ -280,16 +279,16 @@ static void agnx_stop(struct ieee80211_hw *dev)
|
|||
/* make sure hardware will not generate irq */
|
||||
agnx_hw_reset(priv);
|
||||
free_irq(priv->pdev->irq, dev);
|
||||
flush_workqueue(priv->hw->workqueue);
|
||||
// cancel_delayed_work_sync(&priv->periodic_work);
|
||||
flush_workqueue(priv->hw->workqueue);
|
||||
/* cancel_delayed_work_sync(&priv->periodic_work); */
|
||||
unfill_rings(priv);
|
||||
rings_free(priv);
|
||||
}
|
||||
|
||||
static int agnx_config(struct ieee80211_hw *dev,
|
||||
struct ieee80211_conf *conf)
|
||||
static int agnx_config(struct ieee80211_hw *dev, u32 changed)
|
||||
{
|
||||
struct agnx_priv *priv = dev->priv;
|
||||
struct ieee80211_conf *conf = &dev->conf;
|
||||
int channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
|
||||
AGNX_TRACE;
|
||||
|
||||
|
@ -315,7 +314,6 @@ static int agnx_config_interface(struct ieee80211_hw *dev,
|
|||
spin_lock(&priv->lock);
|
||||
|
||||
if (memcmp(conf->bssid, priv->bssid, ETH_ALEN)) {
|
||||
// u32 reghi, reglo;
|
||||
agnx_set_bssid(priv, conf->bssid);
|
||||
memcpy(priv->bssid, conf->bssid, ETH_ALEN);
|
||||
hash_write(priv, conf->bssid, BSSID_STAID);
|
||||
|
@ -425,7 +423,7 @@ static struct ieee80211_ops agnx_ops = {
|
|||
.remove_interface = agnx_remove_interface,
|
||||
.config = agnx_config,
|
||||
.config_interface = agnx_config_interface,
|
||||
.configure_filter = agnx_configure_filter,
|
||||
.configure_filter = agnx_configure_filter,
|
||||
.get_stats = agnx_get_stats,
|
||||
.get_tx_stats = agnx_get_tx_stats,
|
||||
.get_tsf = agnx_get_tsft
|
||||
|
@ -434,11 +432,12 @@ static struct ieee80211_ops agnx_ops = {
|
|||
static void __devexit agnx_pci_remove(struct pci_dev *pdev)
|
||||
{
|
||||
struct ieee80211_hw *dev = pci_get_drvdata(pdev);
|
||||
struct agnx_priv *priv = dev->priv;
|
||||
struct agnx_priv *priv;
|
||||
AGNX_TRACE;
|
||||
|
||||
if (!dev)
|
||||
return;
|
||||
priv = dev->priv;
|
||||
ieee80211_unregister_hw(dev);
|
||||
pci_iounmap(pdev, priv->ctl);
|
||||
pci_iounmap(pdev, priv->data);
|
||||
|
@ -504,7 +503,7 @@ static int __devinit agnx_pci_probe(struct pci_dev *pdev,
|
|||
|
||||
/* Map mem #1 and #2 */
|
||||
priv->ctl = pci_iomap(pdev, 0, mem_len0);
|
||||
// printk(KERN_DEBUG PFX"MEM1 mapped address is 0x%p\n", priv->ctl);
|
||||
/* printk(KERN_DEBUG PFX"MEM1 mapped address is 0x%p\n", priv->ctl); */
|
||||
if (!priv->ctl) {
|
||||
printk(KERN_ERR PFX "Can't map device memory\n");
|
||||
goto err_free_dev;
|
||||
|
|
|
@ -114,7 +114,7 @@ static void mac_address_set(struct agnx_priv *priv)
|
|||
/* FIXME */
|
||||
reg = (mac_addr[0] << 24) | (mac_addr[1] << 16) | mac_addr[2] << 8 | mac_addr[3];
|
||||
iowrite32(reg, ctl + AGNX_RXM_MACHI);
|
||||
reg = (mac_addr[4] << 8) | mac_addr[5];
|
||||
reg = (mac_addr[4] << 8) | mac_addr[5];
|
||||
iowrite32(reg, ctl + AGNX_RXM_MACLO);
|
||||
}
|
||||
|
||||
|
@ -127,7 +127,7 @@ static void receiver_bssid_set(struct agnx_priv *priv, u8 *bssid)
|
|||
/* FIXME */
|
||||
reg = bssid[0] << 24 | (bssid[1] << 16) | (bssid[2] << 8) | bssid[3];
|
||||
iowrite32(reg, ctl + AGNX_RXM_BSSIDHI);
|
||||
reg = (bssid[4] << 8) | bssid[5];
|
||||
reg = (bssid[4] << 8) | bssid[5];
|
||||
iowrite32(reg, ctl + AGNX_RXM_BSSIDLO);
|
||||
|
||||
/* Enable the receiver */
|
||||
|
@ -401,9 +401,9 @@ static void rx_management_init(struct agnx_priv *priv)
|
|||
agnx_write32(ctl, 0x2074, 0x1f171710);
|
||||
agnx_write32(ctl, 0x2078, 0x10100d0d);
|
||||
agnx_write32(ctl, 0x207c, 0x11111010);
|
||||
}
|
||||
else
|
||||
} else {
|
||||
agnx_write32(ctl, AGNX_RXM_DELAY11, 0x0);
|
||||
}
|
||||
agnx_write32(ctl, AGNX_RXM_REQRATE, 0x8195e00);
|
||||
}
|
||||
|
||||
|
@ -476,7 +476,7 @@ static void gain_ctlcnt_init(struct agnx_priv *priv)
|
|||
/* It seemed if we set other bit to 1 the bit 0 will
|
||||
be auto change to 0 */
|
||||
agnx_write32(ctl, AGNX_BM_TXTOPEER, 0x2 | 0x1);
|
||||
// agnx_write32(ctl, AGNX_BM_TXTOPEER, 0x1);
|
||||
/* agnx_write32(ctl, AGNX_BM_TXTOPEER, 0x1); */
|
||||
} /* gain_ctlcnt_init */
|
||||
|
||||
|
||||
|
@ -490,7 +490,7 @@ static void phy_init(struct agnx_priv *priv)
|
|||
/* Load InitialGainTable */
|
||||
gain_table_init(priv);
|
||||
|
||||
agnx_write32(ctl, AGNX_CIR_ADDRWIN, 0x2000000);
|
||||
agnx_write32(ctl, AGNX_CIR_ADDRWIN, 0x2000000);
|
||||
|
||||
/* Clear the following offsets in Memory Range #2: */
|
||||
memset_io(data + 0x5040, 0, 0xa * 4);
|
||||
|
@ -586,7 +586,7 @@ static void phy_init(struct agnx_priv *priv)
|
|||
agnx_write32(ctl, AGNX_GCR_SIFST11B, 0x28);
|
||||
agnx_write32(ctl, AGNX_GCR_CWDETEC, 0x0);
|
||||
agnx_write32(ctl, AGNX_GCR_0X38, 0x1e);
|
||||
// agnx_write32(ctl, AGNX_GCR_BOACT, 0x26);
|
||||
/* agnx_write32(ctl, AGNX_GCR_BOACT, 0x26);*/
|
||||
agnx_write32(ctl, AGNX_GCR_DISCOVMOD, 0x3);
|
||||
|
||||
agnx_write32(ctl, AGNX_GCR_THCAP11A, 0x32);
|
||||
|
@ -810,10 +810,10 @@ static void card_interface_init(struct agnx_priv *priv)
|
|||
}
|
||||
print_hex_dump_bytes(PFX "EEPROM: ", DUMP_PREFIX_NONE, eeprom,
|
||||
ARRAY_SIZE(eeprom));
|
||||
} while(0);
|
||||
} while (0);
|
||||
|
||||
spi_rc_write(ctl, RF_CHIP0, 0x26);
|
||||
reg = agnx_read32(ctl, AGNX_SPI_RLSW);
|
||||
reg = agnx_read32(ctl, AGNX_SPI_RLSW);
|
||||
|
||||
/* Initialize the system interface */
|
||||
system_itf_init(priv);
|
||||
|
@ -874,19 +874,19 @@ static void card_interface_init(struct agnx_priv *priv)
|
|||
/* FIXME Enable the request */
|
||||
/* Check packet length */
|
||||
/* Set maximum packet length */
|
||||
/* agnx_write32(ctl, AGNX_RXM_REQRATE, 0x88195e00); */
|
||||
/* enable_receiver(priv); */
|
||||
/* agnx_write32(ctl, AGNX_RXM_REQRATE, 0x88195e00); */
|
||||
/* enable_receiver(priv); */
|
||||
|
||||
/* Set the Receiver BSSID */
|
||||
receiver_bssid_set(priv, bssid);
|
||||
|
||||
/* FIXME Set to managed mode */
|
||||
set_managed_mode(priv);
|
||||
// set_promiscuous_mode(priv);
|
||||
/* set_scan_mode(priv); */
|
||||
/* set_learn_mode(priv); */
|
||||
// set_promis_and_managed(priv);
|
||||
// set_adhoc_mode(priv);
|
||||
/* set_promiscuous_mode(priv); */
|
||||
/* set_scan_mode(priv); */
|
||||
/* set_learn_mode(priv); */
|
||||
/* set_promis_and_managed(priv); */
|
||||
/* set_adhoc_mode(priv); */
|
||||
|
||||
/* Set the recieve request rate */
|
||||
/* Check packet length */
|
||||
|
|
|
@ -109,12 +109,12 @@ void rf_chips_init(struct agnx_priv *priv)
|
|||
}
|
||||
|
||||
/* Set SPI clock speed to 200NS */
|
||||
reg = agnx_read32(ctl, AGNX_SPI_CFG);
|
||||
reg &= ~0xF;
|
||||
reg |= 0x3;
|
||||
agnx_write32(ctl, AGNX_SPI_CFG, reg);
|
||||
reg = agnx_read32(ctl, AGNX_SPI_CFG);
|
||||
reg &= ~0xF;
|
||||
reg |= 0x3;
|
||||
agnx_write32(ctl, AGNX_SPI_CFG, reg);
|
||||
|
||||
/* Set SPI clock speed to 50NS */
|
||||
/* Set SPI clock speed to 50NS */
|
||||
reg = agnx_read32(ctl, AGNX_SPI_CFG);
|
||||
reg &= ~0xF;
|
||||
reg |= 0x1;
|
||||
|
@ -256,7 +256,7 @@ static void antenna_init(struct agnx_priv *priv, int num_antenna)
|
|||
agnx_write32(ctl, AGNX_GCR_THD0BTFEST, 70);
|
||||
agnx_write32(ctl, AGNX_GCR_SIGHTH, 100);
|
||||
agnx_write32(ctl, AGNX_GCR_SIGLTH, 48);
|
||||
// agnx_write32(ctl, AGNX_GCR_SIGLTH, 16);
|
||||
/* agnx_write32(ctl, AGNX_GCR_SIGLTH, 16); */
|
||||
break;
|
||||
default:
|
||||
printk(KERN_WARNING PFX "Unknow antenna number\n");
|
||||
|
@ -275,8 +275,8 @@ static void chain_update(struct agnx_priv *priv, u32 chain)
|
|||
if (reg == 0x4)
|
||||
spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, reg|0x1000);
|
||||
else if (reg != 0x0)
|
||||
spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, reg|0x1000);
|
||||
else {
|
||||
spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, reg|0x1000);
|
||||
else {
|
||||
if (chain == 3 || chain == 6) {
|
||||
spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, reg|0x1000);
|
||||
agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0x0);
|
||||
|
@ -634,8 +634,7 @@ static void chain_calibrate(struct agnx_priv *priv, struct chains *chains,
|
|||
}
|
||||
} /* chain_calibrate */
|
||||
|
||||
|
||||
static void inline get_calibrete_value(struct agnx_priv *priv, struct chains *chains,
|
||||
static inline void get_calibrete_value(struct agnx_priv *priv, struct chains *chains,
|
||||
unsigned int num)
|
||||
{
|
||||
void __iomem *ctl = priv->ctl;
|
||||
|
@ -652,7 +651,7 @@ static void inline get_calibrete_value(struct agnx_priv *priv, struct chains *ch
|
|||
}
|
||||
|
||||
if (num == 0 || num == 1 || num == 2) {
|
||||
if ( 0 == chains[num].cali)
|
||||
if (0 == chains[num].cali)
|
||||
chains[num].cali = 0xff;
|
||||
else
|
||||
chains[num].cali--;
|
||||
|
@ -669,7 +668,7 @@ static inline void calibra_delay(struct agnx_priv *priv)
|
|||
unsigned int i = 100;
|
||||
|
||||
wmb();
|
||||
while (i--) {
|
||||
while (--i) {
|
||||
reg = (ioread32(ctl + AGNX_ACI_STATUS));
|
||||
if (reg == 0x4000)
|
||||
break;
|
||||
|
|
|
@ -18,7 +18,7 @@ void hash_read(struct agnx_priv *priv, u32 reghi, u32 reglo, u8 sta_id)
|
|||
iowrite32(reglo, ctl + AGNX_RXM_HASH_CMD_LOW);
|
||||
|
||||
reghi = ioread32(ctl + AGNX_RXM_HASH_CMD_HIGH);
|
||||
reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
|
||||
reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
|
||||
printk(PFX "RX hash cmd are : %.8x%.8x\n", reghi, reglo);
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ void hash_write(struct agnx_priv *priv, u8 *mac_addr, u8 sta_id)
|
|||
iowrite32(reghi, ctl + AGNX_RXM_HASH_CMD_HIGH);
|
||||
iowrite32(reglo, ctl + AGNX_RXM_HASH_CMD_LOW);
|
||||
|
||||
reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
|
||||
reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
|
||||
if (!(reglo & 0x80000000))
|
||||
printk(KERN_WARNING PFX "Update hash table failed\n");
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ void hash_delete(struct agnx_priv *priv, u32 reghi, u32 reglo, u8 sta_id)
|
|||
iowrite32(reglo, ctl + AGNX_RXM_HASH_CMD_LOW);
|
||||
reghi = ioread32(ctl + AGNX_RXM_HASH_CMD_HIGH);
|
||||
|
||||
reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
|
||||
reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
|
||||
printk(PFX "RX hash cmd are : %.8x%.8x\n", reghi, reglo);
|
||||
|
||||
}
|
||||
|
@ -69,15 +69,14 @@ void hash_dump(struct agnx_priv *priv, u8 sta_id)
|
|||
void __iomem *ctl = priv->ctl;
|
||||
u32 reghi, reglo;
|
||||
|
||||
reglo = 0x0; /* dump command */
|
||||
reglo|= 0x40000000; /* status bit */
|
||||
reglo = 0x40000000; /* status bit */
|
||||
iowrite32(reglo, ctl + AGNX_RXM_HASH_CMD_LOW);
|
||||
iowrite32(sta_id << 16, ctl + AGNX_RXM_HASH_DUMP_DATA);
|
||||
|
||||
udelay(80);
|
||||
|
||||
reghi = ioread32(ctl + AGNX_RXM_HASH_CMD_HIGH);
|
||||
reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
|
||||
reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
|
||||
printk(PFX "hash cmd are : %.8x%.8x\n", reghi, reglo);
|
||||
reghi = ioread32(ctl + AGNX_RXM_HASH_CMD_FLAG);
|
||||
printk(PFX "hash flag is : %.8x\n", reghi);
|
||||
|
@ -91,7 +90,7 @@ void hash_dump(struct agnx_priv *priv, u8 sta_id)
|
|||
void get_sta_power(struct agnx_priv *priv, struct agnx_sta_power *power, unsigned int sta_idx)
|
||||
{
|
||||
void __iomem *ctl = priv->ctl;
|
||||
memcpy_fromio(power, ctl + AGNX_TXM_STAPOWTEMP + sizeof(*power) * sta_idx,
|
||||
memcpy_fromio(power, ctl + AGNX_TXM_STAPOWTEMP + sizeof(*power) * sta_idx,
|
||||
sizeof(*power));
|
||||
}
|
||||
|
||||
|
@ -100,7 +99,7 @@ set_sta_power(struct agnx_priv *priv, struct agnx_sta_power *power, unsigned int
|
|||
{
|
||||
void __iomem *ctl = priv->ctl;
|
||||
/* FIXME 2. Write Template to offset + station number */
|
||||
memcpy_toio(ctl + AGNX_TXM_STAPOWTEMP + sizeof(*power) * sta_idx,
|
||||
memcpy_toio(ctl + AGNX_TXM_STAPOWTEMP + sizeof(*power) * sta_idx,
|
||||
power, sizeof(*power));
|
||||
}
|
||||
|
||||
|
@ -135,7 +134,7 @@ inline void set_sta(struct agnx_priv *priv, struct agnx_sta *sta, unsigned int s
|
|||
{
|
||||
void __iomem *data = priv->data;
|
||||
|
||||
memcpy_toio(data + AGNX_PDUPOOL + sizeof(*sta) * sta_idx,
|
||||
memcpy_toio(data + AGNX_PDUPOOL + sizeof(*sta) * sta_idx,
|
||||
sta, sizeof(*sta));
|
||||
}
|
||||
|
||||
|
@ -165,7 +164,7 @@ static void sta_tx_workqueue_init(struct agnx_priv *priv, unsigned int sta_idx)
|
|||
|
||||
reg = agnx_set_bits(WORK_QUEUE_VALID, WORK_QUEUE_VALID_SHIFT, 1);
|
||||
reg |= agnx_set_bits(WORK_QUEUE_ACK_TYPE, WORK_QUEUE_ACK_TYPE_SHIFT, 1);
|
||||
// reg |= agnx_set_bits(WORK_QUEUE_ACK_TYPE, WORK_QUEUE_ACK_TYPE_SHIFT, 0);
|
||||
/* reg |= agnx_set_bits(WORK_QUEUE_ACK_TYPE, WORK_QUEUE_ACK_TYPE_SHIFT, 0); */
|
||||
tx_wq.reg2 |= cpu_to_le32(reg);
|
||||
|
||||
/* Suppose all 8 traffic class are used */
|
||||
|
@ -181,7 +180,7 @@ static void sta_traffic_init(struct agnx_sta_traffic *traffic)
|
|||
|
||||
reg = agnx_set_bits(NEW_PACKET, NEW_PACKET_SHIFT, 1);
|
||||
reg |= agnx_set_bits(TRAFFIC_VALID, TRAFFIC_VALID_SHIFT, 1);
|
||||
// reg |= agnx_set_bits(TRAFFIC_ACK_TYPE, TRAFFIC_ACK_TYPE_SHIFT, 1);
|
||||
/* reg |= agnx_set_bits(TRAFFIC_ACK_TYPE, TRAFFIC_ACK_TYPE_SHIFT, 1); */
|
||||
traffic->reg0 = cpu_to_le32(reg);
|
||||
|
||||
/* 3. setting RX Sequence Number to 4095 */
|
||||
|
|
|
@ -16,7 +16,7 @@ struct agnx_hash_cmd {
|
|||
#define PASS 0x00000001
|
||||
#define PASS_SHIFT 1
|
||||
__be32 cmdlo;
|
||||
}__attribute__((__packed__));
|
||||
} __attribute__((__packed__));
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -80,7 +80,7 @@ void routing_table_init(struct agnx_priv *priv)
|
|||
|
||||
disable_receiver(priv);
|
||||
|
||||
for ( type = 0; type < 0x3; type++ ) {
|
||||
for (type = 0; type < 0x3; type++) {
|
||||
for (subtype = 0; subtype < 0x10; subtype++) {
|
||||
/* 1. Set Routing table to R/W and to Return status on Read */
|
||||
reg = (type << ROUTAB_TYPE_SHIFT) |
|
||||
|
@ -89,7 +89,7 @@ void routing_table_init(struct agnx_priv *priv)
|
|||
if (type == ROUTAB_TYPE_DATA) {
|
||||
/* NULL goes to RFP */
|
||||
if (subtype == ROUTAB_SUBTYPE_NULL)
|
||||
// reg |= ROUTAB_ROUTE_RFP;
|
||||
/* reg |= ROUTAB_ROUTE_RFP; */
|
||||
reg |= ROUTAB_ROUTE_CPU;
|
||||
/* QOS NULL goes to CPU */
|
||||
else if (subtype == ROUTAB_SUBTYPE_QOSNULL)
|
||||
|
@ -104,7 +104,7 @@ void routing_table_init(struct agnx_priv *priv)
|
|||
(subtype == ROUTAB_SUBTYPE_QOSDATAPOLL) ||
|
||||
(subtype == ROUTAB_SUBTYPE_QOSDATAACKPOLL))
|
||||
reg |= ROUTAB_ROUTE_ENCRY;
|
||||
// reg |= ROUTAB_ROUTE_CPU;
|
||||
/* reg |= ROUTAB_ROUTE_CPU; */
|
||||
/*Drop NULL and QOS NULL ack, poll and poll ack*/
|
||||
else if ((subtype == ROUTAB_SUBTYPE_NULLACK) ||
|
||||
(subtype == ROUTAB_SUBTYPE_QOSNULLACK) ||
|
||||
|
@ -112,11 +112,11 @@ void routing_table_init(struct agnx_priv *priv)
|
|||
(subtype == ROUTAB_SUBTYPE_QOSNULLPOLL) ||
|
||||
(subtype == ROUTAB_SUBTYPE_NULLPOLLACK) ||
|
||||
(subtype == ROUTAB_SUBTYPE_QOSNULLPOLLACK))
|
||||
// reg |= ROUTAB_ROUTE_DROP;
|
||||
/* reg |= ROUTAB_ROUTE_DROP; */
|
||||
reg |= ROUTAB_ROUTE_CPU;
|
||||
}
|
||||
else
|
||||
} else {
|
||||
reg |= (ROUTAB_ROUTE_CPU);
|
||||
}
|
||||
iowrite32(reg, ctl + AGNX_RXM_ROUTAB);
|
||||
/* Check to verify that the status bit cleared */
|
||||
routing_table_delay();
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
#include "debug.h"
|
||||
#include "phy.h"
|
||||
|
||||
unsigned int rx_frame_cnt = 0;
|
||||
//unsigned int local_tx_sent_cnt = 0;
|
||||
unsigned int rx_frame_cnt;
|
||||
/* unsigned int local_tx_sent_cnt = 0; */
|
||||
|
||||
static inline void disable_rx_engine(struct agnx_priv *priv)
|
||||
{
|
||||
|
@ -242,15 +242,15 @@ static void get_rx_stats(struct agnx_priv *priv, struct agnx_hdr *hdr,
|
|||
memset(stat, 0, sizeof(*stat));
|
||||
/* RSSI */
|
||||
rssi = (u8 *)&hdr->phy_stats_lo;
|
||||
// stat->ssi = (rssi[0] + rssi[1] + rssi[2]) / 3;
|
||||
/* stat->ssi = (rssi[0] + rssi[1] + rssi[2]) / 3; */
|
||||
/* Noise */
|
||||
noise = ioread32(ctl + AGNX_GCR_NOISE0);
|
||||
noise += ioread32(ctl + AGNX_GCR_NOISE1);
|
||||
noise += ioread32(ctl + AGNX_GCR_NOISE2);
|
||||
stat->noise = noise / 3;
|
||||
/* Signal quality */
|
||||
//snr = stat->ssi - stat->noise;
|
||||
if (snr >=0 && snr < 40)
|
||||
/* snr = stat->ssi - stat->noise; */
|
||||
if (snr >= 0 && snr < 40)
|
||||
stat->signal = 5 * snr / 2;
|
||||
else if (snr >= 40)
|
||||
stat->signal = 100;
|
||||
|
@ -269,10 +269,9 @@ static void get_rx_stats(struct agnx_priv *priv, struct agnx_hdr *hdr,
|
|||
|
||||
stat->band = IEEE80211_BAND_2GHZ;
|
||||
stat->freq = agnx_channels[priv->channel - 1].center_freq;
|
||||
// stat->antenna = 3;
|
||||
// stat->mactime = be32_to_cpu(hdr->time_stamp);
|
||||
// stat->channel = priv->channel;
|
||||
|
||||
/* stat->antenna = 3;
|
||||
stat->mactime = be32_to_cpu(hdr->time_stamp);
|
||||
stat->channel = priv->channel; */
|
||||
}
|
||||
|
||||
static inline void combine_hdr_frag(struct ieee80211_hdr *ieeehdr,
|
||||
|
@ -296,7 +295,7 @@ static inline void combine_hdr_frag(struct ieee80211_hdr *ieeehdr,
|
|||
static inline int agnx_packet_check(struct agnx_priv *priv, struct agnx_hdr *agnxhdr,
|
||||
unsigned packet_len)
|
||||
{
|
||||
if (agnx_get_bits(CRC_FAIL, CRC_FAIL_SHIFT, be32_to_cpu(agnxhdr->reg1)) == 1){
|
||||
if (agnx_get_bits(CRC_FAIL, CRC_FAIL_SHIFT, be32_to_cpu(agnxhdr->reg1)) == 1) {
|
||||
printk(PFX "RX: CRC check fail\n");
|
||||
goto drop;
|
||||
}
|
||||
|
@ -320,7 +319,7 @@ void handle_rx_irq(struct agnx_priv *priv)
|
|||
{
|
||||
struct ieee80211_rx_status status;
|
||||
unsigned int len;
|
||||
// AGNX_TRACE;
|
||||
/* AGNX_TRACE; */
|
||||
|
||||
do {
|
||||
struct agnx_desc *desc;
|
||||
|
@ -341,54 +340,54 @@ void handle_rx_irq(struct agnx_priv *priv)
|
|||
|
||||
len = (frag & PACKET_LEN) >> PACKET_LEN_SHIFT;
|
||||
if (agnx_packet_check(priv, hdr, len) == -1) {
|
||||
rx_desc_reusing(priv, i);
|
||||
rx_desc_reusing(priv, i);
|
||||
continue;
|
||||
}
|
||||
skb_put(skb, len);
|
||||
|
||||
do {
|
||||
u16 fctl;
|
||||
u16 fctl;
|
||||
fctl = le16_to_cpu(((struct ieee80211_hdr *)hdr->mac_hdr)->frame_control);
|
||||
if ((fctl & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_BEACON)// && !(fctl & IEEE80211_STYPE_BEACON))
|
||||
if ((fctl & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_BEACON)/* && !(fctl & IEEE80211_STYPE_BEACON)) */
|
||||
dump_ieee80211_hdr((struct ieee80211_hdr *)hdr->mac_hdr, "RX");
|
||||
} while (0);
|
||||
|
||||
if (hdr->_11b0 && !hdr->_11g0) {
|
||||
/* int j; */
|
||||
/* u16 fctl = le16_to_cpu(((struct ieee80211_hdr *)hdr->mac_hdr) */
|
||||
/* ->frame_control); */
|
||||
/* if ( (fctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) { */
|
||||
/* agnx_print_rx_hdr(hdr); */
|
||||
// agnx_print_sta(priv, BSSID_STAID);
|
||||
/* for (j = 0; j < 8; j++) */
|
||||
/* agnx_print_sta_tx_wq(priv, BSSID_STAID, j); */
|
||||
/* } */
|
||||
/* int j;
|
||||
u16 fctl = le16_to_cpu(((struct ieee80211_hdr *)hdr->mac_hdr)
|
||||
->frame_control);
|
||||
if ( (fctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) {
|
||||
agnx_print_rx_hdr(hdr);
|
||||
agnx_print_sta(priv, BSSID_STAID);
|
||||
for (j = 0; j < 8; j++)
|
||||
agnx_print_sta_tx_wq(priv, BSSID_STAID, j);
|
||||
} */
|
||||
|
||||
get_rx_stats(priv, hdr, &status);
|
||||
skb_pull(skb, sizeof(*hdr));
|
||||
combine_hdr_frag((struct ieee80211_hdr *)hdr->mac_hdr, skb);
|
||||
} else if (!hdr->_11b0 && hdr->_11g0) {
|
||||
// int j;
|
||||
/* int j; */
|
||||
agnx_print_rx_hdr(hdr);
|
||||
agnx_print_sta(priv, BSSID_STAID);
|
||||
// for (j = 0; j < 8; j++)
|
||||
/* for (j = 0; j < 8; j++) */
|
||||
agnx_print_sta_tx_wq(priv, BSSID_STAID, 0);
|
||||
|
||||
print_hex_dump_bytes("agnx: RX_PACKET: ", DUMP_PREFIX_NONE,
|
||||
skb->data, skb->len + 8);
|
||||
|
||||
// if (agnx_plcp_get_bitrate_ofdm(&hdr->_11g0) == 0)
|
||||
/* if (agnx_plcp_get_bitrate_ofdm(&hdr->_11g0) == 0) */
|
||||
get_rx_stats(priv, hdr, &status);
|
||||
skb_pull(skb, sizeof(*hdr));
|
||||
combine_hdr_frag((struct ieee80211_hdr *)
|
||||
((void *)&hdr->mac_hdr), skb);
|
||||
// dump_ieee80211_hdr((struct ieee80211_hdr *)skb->data, "RX G");
|
||||
/* dump_ieee80211_hdr((struct ieee80211_hdr *)skb->data, "RX G"); */
|
||||
} else
|
||||
agnx_bug("Unknown packets type");
|
||||
ieee80211_rx_irqsafe(priv->hw, skb, &status);
|
||||
rx_desc_reinit(priv, i);
|
||||
|
||||
} while ( priv->rx.idx++ );
|
||||
} while (priv->rx.idx++);
|
||||
} /* handle_rx_irq */
|
||||
|
||||
static inline void handle_tx_irq(struct agnx_priv *priv, struct agnx_ring *ring)
|
||||
|
@ -415,40 +414,40 @@ static inline void handle_tx_irq(struct agnx_priv *priv, struct agnx_ring *ring)
|
|||
pci_unmap_single(priv->pdev, info->mapping, info->dma_len, PCI_DMA_TODEVICE);
|
||||
|
||||
do {
|
||||
// int j;
|
||||
/* int j; */
|
||||
size_t len;
|
||||
len = info->skb->len - sizeof(struct agnx_hdr) + info->hdr_len;
|
||||
// if (len == 614) {
|
||||
// agnx_print_desc(desc);
|
||||
/* if (len == 614) { */
|
||||
/* agnx_print_desc(desc); */
|
||||
if (info->type == PACKET) {
|
||||
// agnx_print_tx_hdr((struct agnx_hdr *)info->skb->data);
|
||||
/* agnx_print_sta_power(priv, LOCAL_STAID); */
|
||||
/* agnx_print_sta(priv, LOCAL_STAID); */
|
||||
/* // for (j = 0; j < 8; j++) */
|
||||
/* agnx_print_sta_tx_wq(priv, LOCAL_STAID, 0); */
|
||||
// agnx_print_sta_power(priv, BSSID_STAID);
|
||||
// agnx_print_sta(priv, BSSID_STAID);
|
||||
// for (j = 0; j < 8; j++)
|
||||
// agnx_print_sta_tx_wq(priv, BSSID_STAID, 0);
|
||||
/* agnx_print_tx_hdr((struct agnx_hdr *)info->skb->data); */
|
||||
/* agnx_print_sta_power(priv, LOCAL_STAID); */
|
||||
/* agnx_print_sta(priv, LOCAL_STAID); */
|
||||
/* for (j = 0; j < 8; j++) */
|
||||
/* agnx_print_sta_tx_wq(priv, LOCAL_STAID, 0); */
|
||||
/* agnx_print_sta_power(priv, BSSID_STAID); */
|
||||
/* agnx_print_sta(priv, BSSID_STAID); */
|
||||
/* for (j = 0; j < 8; j++) */
|
||||
/* agnx_print_sta_tx_wq(priv, BSSID_STAID, 0); */
|
||||
}
|
||||
// }
|
||||
/* } */
|
||||
} while (0);
|
||||
|
||||
if (info->type == PACKET) {
|
||||
// dump_txm_registers(priv);
|
||||
// dump_rxm_registers(priv);
|
||||
// dump_bm_registers(priv);
|
||||
// dump_cir_registers(priv);
|
||||
/* dump_txm_registers(priv);
|
||||
dump_rxm_registers(priv);
|
||||
dump_bm_registers(priv);
|
||||
dump_cir_registers(priv); */
|
||||
}
|
||||
|
||||
if (info->type == PACKET) {
|
||||
// struct ieee80211_hdr *hdr;
|
||||
/* struct ieee80211_hdr *hdr; */
|
||||
struct ieee80211_tx_info *txi = IEEE80211_SKB_CB(info->skb);
|
||||
|
||||
skb_pull(info->skb, sizeof(struct agnx_hdr));
|
||||
memcpy(skb_push(info->skb, info->hdr_len), &info->hdr, info->hdr_len);
|
||||
|
||||
// dump_ieee80211_hdr((struct ieee80211_hdr *)info->skb->data, "TX_HANDLE");
|
||||
/* dump_ieee80211_hdr((struct ieee80211_hdr *)info->skb->data, "TX_HANDLE"); */
|
||||
/* print_hex_dump_bytes("agnx: TX_HANDLE: ", DUMP_PREFIX_NONE, */
|
||||
/* info->skb->data, info->skb->len); */
|
||||
|
||||
|
@ -462,7 +461,7 @@ static inline void handle_tx_irq(struct agnx_priv *priv, struct agnx_ring *ring)
|
|||
/* ieee80211_tx_status_irqsafe(priv->hw, info->skb, &(info->tx_status)); */
|
||||
/* } else */
|
||||
/* dev_kfree_skb_irq(info->skb); */
|
||||
}
|
||||
}
|
||||
memset(desc, 0, sizeof(*desc));
|
||||
memset(info, 0, sizeof(*info));
|
||||
}
|
||||
|
@ -485,7 +484,7 @@ void handle_txd_irq(struct agnx_priv *priv)
|
|||
|
||||
void handle_other_irq(struct agnx_priv *priv)
|
||||
{
|
||||
// void __iomem *ctl = priv->ctl;
|
||||
/* void __iomem *ctl = priv->ctl; */
|
||||
u32 status = priv->irq_status;
|
||||
void __iomem *ctl = priv->ctl;
|
||||
u32 reg;
|
||||
|
@ -526,11 +525,11 @@ void handle_other_irq(struct agnx_priv *priv)
|
|||
iowrite32(reg, ctl + AGNX_INT_MASK);
|
||||
iowrite32(IRQ_RX_FRAME, ctl + AGNX_INT_STAT);
|
||||
printk(PFX "IRQ: RX Frame\n");
|
||||
rx_frame_cnt++;
|
||||
rx_frame_cnt++;
|
||||
}
|
||||
if (status & IRQ_ERR_INT) {
|
||||
iowrite32(IRQ_ERR_INT, ctl + AGNX_INT_STAT);
|
||||
// agnx_hw_reset(priv);
|
||||
/* agnx_hw_reset(priv); */
|
||||
printk(PFX "IRQ: Error Interrupt\n");
|
||||
}
|
||||
if (status & IRQ_TX_QUE_FULL)
|
||||
|
@ -558,14 +557,14 @@ void handle_other_irq(struct agnx_priv *priv)
|
|||
|
||||
static inline void route_flag_set(struct agnx_hdr *txhdr)
|
||||
{
|
||||
// u32 reg = 0;
|
||||
/* u32 reg = 0; */
|
||||
|
||||
/* FIXME */
|
||||
/* reg = (0x7 << ROUTE_COMPRESSION_SHIFT) & ROUTE_COMPRESSION; */
|
||||
/* txhdr->reg5 = cpu_to_be32(reg); */
|
||||
txhdr->reg5 = (0xa << 0x0) | (0x7 << 0x18);
|
||||
// txhdr->reg5 = cpu_to_be32((0xa << 0x0) | (0x7 << 0x18));
|
||||
// txhdr->reg5 = cpu_to_be32(0x7 << 0x0);
|
||||
/* reg = (0x7 << ROUTE_COMPRESSION_SHIFT) & ROUTE_COMPRESSION; */
|
||||
/* txhdr->reg5 = cpu_to_be32(reg); */
|
||||
txhdr->reg5 = (0xa << 0x0) | (0x7 << 0x18);
|
||||
/* txhdr->reg5 = cpu_to_be32((0xa << 0x0) | (0x7 << 0x18)); */
|
||||
/* txhdr->reg5 = cpu_to_be32(0x7 << 0x0); */
|
||||
}
|
||||
|
||||
/* Return 0 if no match */
|
||||
|
@ -579,12 +578,29 @@ static inline unsigned int get_power_level(unsigned int rate, unsigned int anten
|
|||
case 55:
|
||||
case 60:
|
||||
case 90:
|
||||
case 120: power_level = 22; break;
|
||||
case 180: power_level = 19; break;
|
||||
case 240: power_level = 18; break;
|
||||
case 360: power_level = 16; break;
|
||||
case 480: power_level = 15; break;
|
||||
case 540: power_level = 14; break;
|
||||
case 120:
|
||||
power_level = 22;
|
||||
break;
|
||||
|
||||
case 180:
|
||||
power_level = 19;
|
||||
break;
|
||||
|
||||
case 240:
|
||||
power_level = 18;
|
||||
break;
|
||||
|
||||
case 360:
|
||||
power_level = 16;
|
||||
break;
|
||||
|
||||
case 480:
|
||||
power_level = 15;
|
||||
break;
|
||||
|
||||
case 540:
|
||||
power_level = 14;
|
||||
break;
|
||||
default:
|
||||
agnx_bug("Error rate setting\n");
|
||||
}
|
||||
|
@ -604,30 +620,30 @@ static inline void fill_agnx_hdr(struct agnx_priv *priv, struct agnx_info *tx_in
|
|||
|
||||
memset(txhdr, 0, sizeof(*txhdr));
|
||||
|
||||
// reg = agnx_set_bits(STATION_ID, STATION_ID_SHIFT, LOCAL_STAID);
|
||||
/* reg = agnx_set_bits(STATION_ID, STATION_ID_SHIFT, LOCAL_STAID); */
|
||||
reg = agnx_set_bits(STATION_ID, STATION_ID_SHIFT, BSSID_STAID);
|
||||
reg |= agnx_set_bits(WORKQUEUE_ID, WORKQUEUE_ID_SHIFT, 0);
|
||||
txhdr->reg4 = cpu_to_be32(reg);
|
||||
|
||||
/* Set the Hardware Sequence Number to 1? */
|
||||
reg = agnx_set_bits(SEQUENCE_NUMBER, SEQUENCE_NUMBER_SHIFT, 0);
|
||||
// reg = agnx_set_bits(SEQUENCE_NUMBER, SEQUENCE_NUMBER_SHIFT, 1);
|
||||
/* reg = agnx_set_bits(SEQUENCE_NUMBER, SEQUENCE_NUMBER_SHIFT, 1); */
|
||||
reg |= agnx_set_bits(MAC_HDR_LEN, MAC_HDR_LEN_SHIFT, tx_info->hdr_len);
|
||||
txhdr->reg1 = cpu_to_be32(reg);
|
||||
/* Set the agnx_hdr's MAC header */
|
||||
memcpy(txhdr->mac_hdr, &tx_info->hdr, tx_info->hdr_len);
|
||||
|
||||
reg = agnx_set_bits(ACK, ACK_SHIFT, 1);
|
||||
// reg = agnx_set_bits(ACK, ACK_SHIFT, 0);
|
||||
/* reg = agnx_set_bits(ACK, ACK_SHIFT, 0); */
|
||||
reg |= agnx_set_bits(MULTICAST, MULTICAST_SHIFT, 0);
|
||||
// reg |= agnx_set_bits(MULTICAST, MULTICAST_SHIFT, 1);
|
||||
/* reg |= agnx_set_bits(MULTICAST, MULTICAST_SHIFT, 1); */
|
||||
reg |= agnx_set_bits(RELAY, RELAY_SHIFT, 0);
|
||||
reg |= agnx_set_bits(TM, TM_SHIFT, 0);
|
||||
txhdr->reg0 = cpu_to_be32(reg);
|
||||
|
||||
/* Set the long and short retry limits */
|
||||
txhdr->tx.short_retry_limit = tx_info->txi->control.rates[0].count;
|
||||
txhdr->tx.long_retry_limit = tx_info->txi->control.rates[0].count;
|
||||
txhdr->tx.short_retry_limit = tx_info->txi->control.rates[0].count;
|
||||
txhdr->tx.long_retry_limit = tx_info->txi->control.rates[0].count;
|
||||
|
||||
/* FIXME */
|
||||
len = tx_info->skb->len - sizeof(*txhdr) + tx_info->hdr_len + FCS_LEN;
|
||||
|
@ -652,23 +668,23 @@ static void txm_power_set(struct agnx_priv *priv,
|
|||
if (txi->control.rates[0].idx < 0) {
|
||||
/* For B mode Short Preamble */
|
||||
reg = agnx_set_bits(PHY_MODE, PHY_MODE_SHIFT, AGNX_MODE_80211B_SHORT);
|
||||
// control->tx_rate = -control->tx_rate;
|
||||
/* control->tx_rate = -control->tx_rate; */
|
||||
} else
|
||||
reg = agnx_set_bits(PHY_MODE, PHY_MODE_SHIFT, AGNX_MODE_80211G);
|
||||
// reg = agnx_set_bits(PHY_MODE, PHY_MODE_SHIFT, AGNX_MODE_80211B_LONG);
|
||||
/* reg = agnx_set_bits(PHY_MODE, PHY_MODE_SHIFT, AGNX_MODE_80211B_LONG); */
|
||||
reg |= agnx_set_bits(SIGNAL, SIGNAL_SHIFT, 0xB);
|
||||
reg |= agnx_set_bits(RATE, RATE_SHIFT, 0xB);
|
||||
// reg |= agnx_set_bits(POWER_LEVEL, POWER_LEVEL_SHIFT, 15);
|
||||
/* reg |= agnx_set_bits(POWER_LEVEL, POWER_LEVEL_SHIFT, 15); */
|
||||
reg |= agnx_set_bits(POWER_LEVEL, POWER_LEVEL_SHIFT, 20);
|
||||
/* if rate < 11M set it to 0 */
|
||||
reg |= agnx_set_bits(NUM_TRANSMITTERS, NUM_TRANSMITTERS_SHIFT, 1);
|
||||
// reg |= agnx_set_bits(EDCF, EDCF_SHIFT, 1);
|
||||
// reg |= agnx_set_bits(TIFS, TIFS_SHIFT, 1);
|
||||
/* reg |= agnx_set_bits(EDCF, EDCF_SHIFT, 1); */
|
||||
/* reg |= agnx_set_bits(TIFS, TIFS_SHIFT, 1); */
|
||||
|
||||
power.reg = reg;
|
||||
// power.reg = cpu_to_le32(reg);
|
||||
/* power.reg = cpu_to_le32(reg); */
|
||||
|
||||
// set_sta_power(priv, &power, LOCAL_STAID);
|
||||
/* set_sta_power(priv, &power, LOCAL_STAID); */
|
||||
set_sta_power(priv, &power, BSSID_STAID);
|
||||
}
|
||||
|
||||
|
@ -759,24 +775,24 @@ static int __agnx_tx(struct agnx_priv *priv, struct sk_buff *skb,
|
|||
|
||||
txm_power_set(priv, txi);
|
||||
|
||||
/* do { */
|
||||
/* int j; */
|
||||
/* size_t len; */
|
||||
/* len = skb->len - hdr_info->dma_len + hdr_info->hdr_len; */
|
||||
/* // if (len == 614) { */
|
||||
/* agnx_print_desc(hdr_desc); */
|
||||
/* agnx_print_desc(frag_desc); */
|
||||
/* agnx_print_tx_hdr((struct agnx_hdr *)skb->data); */
|
||||
/* agnx_print_sta_power(priv, LOCAL_STAID); */
|
||||
/* agnx_print_sta(priv, LOCAL_STAID); */
|
||||
/* for (j = 0; j < 8; j++) */
|
||||
/* agnx_print_sta_tx_wq(priv, LOCAL_STAID, j); */
|
||||
/* agnx_print_sta_power(priv, BSSID_STAID); */
|
||||
/* agnx_print_sta(priv, BSSID_STAID); */
|
||||
/* for (j = 0; j < 8; j++) */
|
||||
/* agnx_print_sta_tx_wq(priv, BSSID_STAID, j); */
|
||||
/* // } */
|
||||
/* } while (0); */
|
||||
/* do { */
|
||||
/* int j; */
|
||||
/* size_t len; */
|
||||
/* len = skb->len - hdr_info->dma_len + hdr_info->hdr_len; */
|
||||
/* if (len == 614) { */
|
||||
/* agnx_print_desc(hdr_desc); */
|
||||
/* agnx_print_desc(frag_desc); */
|
||||
/* agnx_print_tx_hdr((struct agnx_hdr *)skb->data); */
|
||||
/* agnx_print_sta_power(priv, LOCAL_STAID); */
|
||||
/* agnx_print_sta(priv, LOCAL_STAID); */
|
||||
/* for (j = 0; j < 8; j++) */
|
||||
/* agnx_print_sta_tx_wq(priv, LOCAL_STAID, j); */
|
||||
/* agnx_print_sta_power(priv, BSSID_STAID); */
|
||||
/* agnx_print_sta(priv, BSSID_STAID); */
|
||||
/* for (j = 0; j < 8; j++) */
|
||||
/* agnx_print_sta_tx_wq(priv, BSSID_STAID, j); */
|
||||
/* } */
|
||||
/* } while (0); */
|
||||
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
|
@ -787,7 +803,7 @@ static int __agnx_tx(struct agnx_priv *priv, struct sk_buff *skb,
|
|||
reg = (ioread32(priv->ctl + AGNX_CIR_TXMCTL));
|
||||
reg |= 0x8;
|
||||
iowrite32((reg), priv->ctl + AGNX_CIR_TXMCTL);
|
||||
}while (0);
|
||||
} while (0);
|
||||
|
||||
/* Trigger TXD */
|
||||
do {
|
||||
|
@ -795,7 +811,7 @@ static int __agnx_tx(struct agnx_priv *priv, struct sk_buff *skb,
|
|||
reg = (ioread32(priv->ctl + AGNX_CIR_TXDCTL));
|
||||
reg |= 0x8;
|
||||
iowrite32((reg), priv->ctl + AGNX_CIR_TXDCTL);
|
||||
}while (0);
|
||||
} while (0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -807,12 +823,12 @@ int _agnx_tx(struct agnx_priv *priv, struct sk_buff *skb)
|
|||
if (tx_packet_check(skb))
|
||||
return 0;
|
||||
|
||||
/* print_hex_dump_bytes("agnx: TX_PACKET: ", DUMP_PREFIX_NONE, */
|
||||
/* skb->data, skb->len); */
|
||||
/* print_hex_dump_bytes("agnx: TX_PACKET: ", DUMP_PREFIX_NONE, */
|
||||
/* skb->data, skb->len); */
|
||||
|
||||
fctl = le16_to_cpu(*((__le16 *)skb->data));
|
||||
fctl = le16_to_cpu(*((__le16 *)skb->data));
|
||||
|
||||
if ( (fctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA )
|
||||
if ((fctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)
|
||||
return __agnx_tx(priv, skb, &priv->txd);
|
||||
else
|
||||
return __agnx_tx(priv, skb, &priv->txm);
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
#include <linux/cdev.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
|
@ -313,15 +312,16 @@ static int __devinit map_bars(struct ape_dev *ape, struct pci_dev *dev)
|
|||
continue;
|
||||
/* do not map BARs with address 0 */
|
||||
if (!bar_start || !bar_end) {
|
||||
printk(KERN_DEBUG "BAR #%d is not present?!\n", i);
|
||||
printk(KERN_DEBUG "BAR #%d is not present?!\n", i);
|
||||
rc = -1;
|
||||
goto fail;
|
||||
}
|
||||
bar_length = bar_end - bar_start + 1;
|
||||
/* BAR length is less than driver requires? */
|
||||
if (bar_length < bar_min_len[i]) {
|
||||
printk(KERN_DEBUG "BAR #%d length = %lu bytes but driver "
|
||||
"requires at least %lu bytes\n", i, bar_length, bar_min_len[i]);
|
||||
printk(KERN_DEBUG "BAR #%d length = %lu bytes but driver "
|
||||
"requires at least %lu bytes\n",
|
||||
i, bar_length, bar_min_len[i]);
|
||||
rc = -1;
|
||||
goto fail;
|
||||
}
|
||||
|
@ -333,8 +333,8 @@ static int __devinit map_bars(struct ape_dev *ape, struct pci_dev *dev)
|
|||
rc = -1;
|
||||
goto fail;
|
||||
}
|
||||
printk(KERN_DEBUG "BAR[%d] mapped at 0x%p with length %lu(/%lu).\n", i,
|
||||
ape->bar[i], bar_min_len[i], bar_length);
|
||||
printk(KERN_DEBUG "BAR[%d] mapped at 0x%p with length %lu(/%lu).\n", i,
|
||||
ape->bar[i], bar_min_len[i], bar_length);
|
||||
}
|
||||
/* succesfully mapped all required BAR regions */
|
||||
rc = 0;
|
||||
|
@ -427,11 +427,13 @@ static int ape_sg_to_chdma_table(struct scatterlist *sgl, int nents, int first,
|
|||
dma_addr_t next = sg_dma_address(&sgl[i + 1]);
|
||||
/* length of this entry i */
|
||||
len = sg_dma_len(&sgl[i]);
|
||||
printk(KERN_DEBUG "%04d: addr=0x%08x length=0x%08x\n", i, addr, len);
|
||||
printk(KERN_DEBUG "%04d: addr=0x%Lx length=0x%08x\n", i,
|
||||
(unsigned long long)addr, len);
|
||||
/* entry i + 1 is non-contiguous with entry i? */
|
||||
if (next != addr + len) {
|
||||
/* TODO create entry here (we could overwrite i) */
|
||||
printk(KERN_DEBUG "%4d: cont_addr=0x%08x cont_len=0x%08x\n", j, cont_addr, cont_len);
|
||||
printk(KERN_DEBUG "%4d: cont_addr=0x%Lx cont_len=0x%08x\n", j,
|
||||
(unsigned long long)cont_addr, cont_len);
|
||||
/* set descriptor for contiguous transfer */
|
||||
ape_chdma_desc_set(&desc[j], cont_addr, ep_addr, cont_len);
|
||||
/* next end point memory address */
|
||||
|
@ -447,8 +449,10 @@ static int ape_sg_to_chdma_table(struct scatterlist *sgl, int nents, int first,
|
|||
addr = next;
|
||||
}
|
||||
/* TODO create entry here (we could overwrite i) */
|
||||
printk(KERN_DEBUG "%04d: addr=0x%08x length=0x%08x\n", i, addr, len);
|
||||
printk(KERN_DEBUG "%4d: cont_addr=0x%08x length=0x%08x\n", j, cont_addr, cont_len);
|
||||
printk(KERN_DEBUG "%04d: addr=0x%Lx length=0x%08x\n", i,
|
||||
(unsigned long long)addr, len);
|
||||
printk(KERN_DEBUG "%4d: cont_addr=0x%Lx length=0x%08x\n", j,
|
||||
(unsigned long long)cont_addr, cont_len);
|
||||
j++;
|
||||
return j;
|
||||
}
|
||||
|
@ -467,15 +471,14 @@ static inline int compare(u32 *p, u32 *q, int len)
|
|||
} else {
|
||||
fail++;
|
||||
/* show the first few miscompares */
|
||||
if (fail < 10) {
|
||||
printk(KERN_DEBUG "[%p] = 0x%08x != [%p] = 0x%08x ?!\n", p, *p, q, *q);
|
||||
/* but stop after a while */
|
||||
} else if (fail == 10) {
|
||||
printk(KERN_DEBUG "---more errors follow! not printed---\n");
|
||||
} else {
|
||||
if (fail < 10)
|
||||
printk(KERN_DEBUG "[%p] = 0x%08x != [%p] = 0x%08x ?!\n", p, *p, q, *q);
|
||||
/* but stop after a while */
|
||||
else if (fail == 10)
|
||||
printk(KERN_DEBUG "---more errors follow! not printed---\n");
|
||||
else
|
||||
/* stop compare after this many errors */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
p++;
|
||||
q++;
|
||||
|
@ -528,7 +531,7 @@ static int __devinit dma_test(struct ape_dev *ape, struct pci_dev *dev)
|
|||
printk(KERN_DEBUG "ape->table_virt = 0x%p.\n", ape->table_virt);
|
||||
|
||||
if (!write_header || !read_header || !ape->table_virt)
|
||||
goto fail;
|
||||
goto fail;
|
||||
|
||||
/* allocate and map coherently-cached memory for a DMA-able buffer */
|
||||
/* @see Documentation/PCI/PCI-DMA-mapping.txt, near line 318 */
|
||||
|
@ -565,9 +568,8 @@ static int __devinit dma_test(struct ape_dev *ape, struct pci_dev *dev)
|
|||
/* read 8192 bytes from RC buffer to EP address 4096 */
|
||||
ape_chdma_desc_set(&ape->table_virt->desc[n], buffer_bus, 4096, 2 * PAGE_SIZE);
|
||||
#if 1
|
||||
for (i = 0; i < 255; i++) {
|
||||
for (i = 0; i < 255; i++)
|
||||
ape_chdma_desc_set(&ape->table_virt->desc[i], buffer_bus, 4096, 2 * PAGE_SIZE);
|
||||
}
|
||||
/* index of last descriptor */
|
||||
n = i - 1;
|
||||
#endif
|
||||
|
@ -647,7 +649,7 @@ static int __devinit dma_test(struct ape_dev *ape, struct pci_dev *dev)
|
|||
printk(KERN_DEBUG "EPLAST = %u, n = %d\n", eplast, n);
|
||||
if (eplast == n) {
|
||||
printk(KERN_DEBUG "DONE\n");
|
||||
/* print IRQ count before the transfer */
|
||||
/* print IRQ count before the transfer */
|
||||
printk(KERN_DEBUG "#IRQs during transfer: %d\n", ape->irq_count - irq_count);
|
||||
break;
|
||||
}
|
||||
|
@ -661,9 +663,9 @@ static int __devinit dma_test(struct ape_dev *ape, struct pci_dev *dev)
|
|||
n = 0;
|
||||
ape_chdma_desc_set(&ape->table_virt->desc[n], buffer_bus + 8192, 4096, 2 * PAGE_SIZE);
|
||||
#if 1
|
||||
for (i = 0; i < 255; i++) {
|
||||
for (i = 0; i < 255; i++)
|
||||
ape_chdma_desc_set(&ape->table_virt->desc[i], buffer_bus + 8192, 4096, 2 * PAGE_SIZE);
|
||||
}
|
||||
|
||||
/* index of last descriptor */
|
||||
n = i - 1;
|
||||
#endif
|
||||
|
@ -691,7 +693,7 @@ static int __devinit dma_test(struct ape_dev *ape, struct pci_dev *dev)
|
|||
w = (u32)(n + 1);
|
||||
/* enable updates of eplast for each descriptor completion */
|
||||
w |= (u32)(1UL << 18)/*global EPLAST_EN*/;
|
||||
#if 0 // test variable, make a module option later
|
||||
#if 0 /* test variable, make a module option later */
|
||||
/* enable MSI for each descriptor completion */
|
||||
if (ape->msi_enabled)
|
||||
w |= (1UL << 17)/*global MSI*/;
|
||||
|
@ -715,7 +717,7 @@ static int __devinit dma_test(struct ape_dev *ape, struct pci_dev *dev)
|
|||
/** memory write barrier */
|
||||
wmb();
|
||||
/** dummy read to flush posted writes */
|
||||
//(void)ioread32();
|
||||
/* (void) ioread32(); */
|
||||
|
||||
printk(KERN_DEBUG "POLL FOR WRITE:\n");
|
||||
/* poll for completion, 1000 times 1 millisecond */
|
||||
|
@ -844,7 +846,7 @@ static int __devinit probe(struct pci_dev *dev, const struct pci_device_id *id)
|
|||
}
|
||||
ape->got_regions = 1;
|
||||
|
||||
#if 1 // @todo For now, disable 64-bit, because I do not understand the implications (DAC!)
|
||||
#if 1 /* @todo For now, disable 64-bit, because I do not understand the implications (DAC!) */
|
||||
/* query for DMA transfer */
|
||||
/* @see Documentation/PCI/PCI-DMA-mapping.txt */
|
||||
if (!pci_set_dma_mask(dev, DMA_64BIT_MASK)) {
|
||||
|
@ -947,7 +949,8 @@ static void __devexit remove(struct pci_dev *dev)
|
|||
struct ape_dev *ape;
|
||||
printk(KERN_DEBUG "remove(0x%p)\n", dev);
|
||||
if ((dev == 0) || (dev->dev.driver_data == 0)) {
|
||||
printk(KERN_DEBUG "remove(dev = 0x%p) dev->dev.driver_data = 0x%p\n", dev, dev->dev.driver_data);
|
||||
printk(KERN_DEBUG "remove(dev = 0x%p) dev->dev.driver_data = 0x%p\n",
|
||||
dev, (dev? dev->dev.driver_data: NULL));
|
||||
return;
|
||||
}
|
||||
ape = (struct ape_dev *)dev->dev.driver_data;
|
||||
|
@ -1048,10 +1051,9 @@ static ssize_t sg_write(struct file *file, const char __user *buf, size_t count,
|
|||
printk(KERN_DEBUG DRV_NAME "_write(buf=0x%p, count=%lld, pos=%llu)\n",
|
||||
buf, (s64)count, (u64)*pos);
|
||||
/* TODO transfer boundaries at PAGE_SIZE granularity */
|
||||
while (remaining > 0)
|
||||
{
|
||||
while (remaining > 0) {
|
||||
/* limit DMA transfer size */
|
||||
transfer_len = (remaining < APE_CHDMA_MAX_TRANSFER_LEN)? remaining:
|
||||
transfer_len = (remaining < APE_CHDMA_MAX_TRANSFER_LEN) ? remaining :
|
||||
APE_CHDMA_MAX_TRANSFER_LEN;
|
||||
/* get all user space buffer pages and create a scattergather list */
|
||||
sgm_map_user_pages(ape->sgm, transfer_addr, transfer_len, 0/*read from userspace*/);
|
||||
|
@ -1085,12 +1087,12 @@ static ssize_t sg_write(struct file *file, const char __user *buf, size_t count,
|
|||
/*
|
||||
* character device file operations
|
||||
*/
|
||||
static struct file_operations sg_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = sg_open,
|
||||
.release = sg_close,
|
||||
.read = sg_read,
|
||||
.write = sg_write,
|
||||
static const struct file_operations sg_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = sg_open,
|
||||
.release = sg_close,
|
||||
.read = sg_read,
|
||||
.write = sg_write,
|
||||
};
|
||||
|
||||
/* sg_init() - Initialize character device
|
||||
|
@ -1158,12 +1160,12 @@ static struct pci_driver pci_driver = {
|
|||
*/
|
||||
static int __init alterapciechdma_init(void)
|
||||
{
|
||||
int rc = 0;
|
||||
int rc = 0;
|
||||
printk(KERN_DEBUG DRV_NAME " init(), built at " __DATE__ " " __TIME__ "\n");
|
||||
/* register this driver with the PCI bus driver */
|
||||
rc = pci_register_driver(&pci_driver);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
return rc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -2649,14 +2649,22 @@ static void binder_vma_open(struct vm_area_struct *vma)
|
|||
{
|
||||
struct binder_proc *proc = vma->vm_private_data;
|
||||
if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE)
|
||||
printk(KERN_INFO "binder: %d open vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, pgprot_val(vma->vm_page_prot));
|
||||
printk(KERN_INFO
|
||||
"binder: %d open vm area %lx-%lx (%ld K) vma %lx pagep %lx\n",
|
||||
proc->pid, vma->vm_start, vma->vm_end,
|
||||
(vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags,
|
||||
(unsigned long)pgprot_val(vma->vm_page_prot));
|
||||
dump_stack();
|
||||
}
|
||||
static void binder_vma_close(struct vm_area_struct *vma)
|
||||
{
|
||||
struct binder_proc *proc = vma->vm_private_data;
|
||||
if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE)
|
||||
printk(KERN_INFO "binder: %d close vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, pgprot_val(vma->vm_page_prot));
|
||||
printk(KERN_INFO
|
||||
"binder: %d close vm area %lx-%lx (%ld K) vma %lx pagep %lx\n",
|
||||
proc->pid, vma->vm_start, vma->vm_end,
|
||||
(vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags,
|
||||
(unsigned long)pgprot_val(vma->vm_page_prot));
|
||||
proc->vma = NULL;
|
||||
}
|
||||
|
||||
|
@ -2677,7 +2685,11 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
|
|||
vma->vm_end = vma->vm_start + SZ_4M;
|
||||
|
||||
if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE)
|
||||
printk(KERN_INFO "binder_mmap: %d %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, pgprot_val(vma->vm_page_prot));
|
||||
printk(KERN_INFO
|
||||
"binder_mmap: %d %lx-%lx (%ld K) vma %lx pagep %lx\n",
|
||||
proc->pid, vma->vm_start, vma->vm_end,
|
||||
(vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags,
|
||||
(unsigned long)pgprot_val(vma->vm_page_prot));
|
||||
|
||||
if (vma->vm_flags & FORBIDDEN_MMAP_FLAGS) {
|
||||
ret = -EPERM;
|
||||
|
|
|
@ -225,7 +225,7 @@ static int __init ram_console_init(struct ram_console_buffer *buffer,
|
|||
buffer_size - sizeof(struct ram_console_buffer);
|
||||
|
||||
if (ram_console_buffer_size > buffer_size) {
|
||||
pr_err("ram_console: buffer %p, invalid size %d, datasize %d\n",
|
||||
pr_err("ram_console: buffer %p, invalid size %zu, datasize %zu\n",
|
||||
buffer, buffer_size, ram_console_buffer_size);
|
||||
return 0;
|
||||
}
|
||||
|
@ -235,8 +235,8 @@ static int __init ram_console_init(struct ram_console_buffer *buffer,
|
|||
ECC_BLOCK_SIZE) + 1) * ECC_SIZE;
|
||||
|
||||
if (ram_console_buffer_size > buffer_size) {
|
||||
pr_err("ram_console: buffer %p, invalid size %d, "
|
||||
"non-ecc datasize %d\n",
|
||||
pr_err("ram_console: buffer %p, invalid size %zu, "
|
||||
"non-ecc datasize %zu\n",
|
||||
buffer, buffer_size, ram_console_buffer_size);
|
||||
return 0;
|
||||
}
|
||||
|
@ -322,7 +322,7 @@ static int ram_console_driver_probe(struct platform_device *pdev)
|
|||
}
|
||||
buffer_size = res->end - res->start + 1;
|
||||
start = res->start;
|
||||
printk(KERN_INFO "ram_console: got buffer at %x, size %x\n",
|
||||
printk(KERN_INFO "ram_console: got buffer at %zx, size %zx\n",
|
||||
start, buffer_size);
|
||||
buffer = ioremap(res->start, buffer_size);
|
||||
if (buffer == NULL) {
|
||||
|
|
|
@ -56,10 +56,10 @@ MODULE_AUTHOR("Jakub Schmidtke, sjakub@gmail.com");
|
|||
MODULE_DESCRIPTION("Asus OLED Driver v" ASUS_OLED_VERSION);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
static struct class *oled_class = 0;
|
||||
static int oled_num = 0;
|
||||
static struct class *oled_class;
|
||||
static int oled_num;
|
||||
|
||||
static uint start_off = 0;
|
||||
static uint start_off;
|
||||
|
||||
module_param(start_off, uint, 0644);
|
||||
|
||||
|
@ -80,20 +80,20 @@ struct oled_dev_desc_str {
|
|||
};
|
||||
|
||||
/* table of devices that work with this driver */
|
||||
static struct usb_device_id id_table [] = {
|
||||
static struct usb_device_id id_table[] = {
|
||||
{ USB_DEVICE(0x0b05, 0x1726) }, // Asus G1/G2 (and variants)
|
||||
{ USB_DEVICE(0x0b05, 0x175b) }, // Asus G50V (and possibly others - G70? G71?)
|
||||
{ },
|
||||
};
|
||||
|
||||
/* parameters of specific devices */
|
||||
static struct oled_dev_desc_str oled_dev_desc_table [] = {
|
||||
static struct oled_dev_desc_str oled_dev_desc_table[] = {
|
||||
{ 0x0b05, 0x1726, 128, PACK_MODE_G1, "G1/G2" },
|
||||
{ 0x0b05, 0x175b, 256, PACK_MODE_G50, "G50" },
|
||||
{ },
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE (usb, id_table);
|
||||
MODULE_DEVICE_TABLE(usb, id_table);
|
||||
|
||||
#define SETUP_PACKET_HEADER(packet, val1, val2, val3, val4, val5, val6, val7) \
|
||||
do { \
|
||||
|
@ -107,7 +107,7 @@ MODULE_DEVICE_TABLE (usb, id_table);
|
|||
packet->header.value6 = val5; \
|
||||
packet->header.value7 = val6; \
|
||||
packet->header.value8 = val7; \
|
||||
} while(0);
|
||||
} while (0);
|
||||
|
||||
struct asus_oled_header {
|
||||
uint8_t magic1;
|
||||
|
@ -160,10 +160,12 @@ static void enable_oled(struct asus_oled_dev *odev, uint8_t enabl)
|
|||
|
||||
SETUP_PACKET_HEADER(packet, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00);
|
||||
|
||||
if (enabl) packet->bitmap[0] = 0xaf;
|
||||
else packet->bitmap[0] = 0xae;
|
||||
if (enabl)
|
||||
packet->bitmap[0] = 0xaf;
|
||||
else
|
||||
packet->bitmap[0] = 0xae;
|
||||
|
||||
for (a=0; a<1; a++) {
|
||||
for (a = 0; a < 1; a++) {
|
||||
retval = usb_bulk_msg(odev->udev,
|
||||
usb_sndbulkpipe(odev->udev, 2),
|
||||
packet,
|
||||
|
@ -252,7 +254,7 @@ static void send_packets(struct usb_device *udev, struct asus_oled_packet *packe
|
|||
}
|
||||
}
|
||||
|
||||
static void send_packet(struct usb_device *udev, struct asus_oled_packet *packet, size_t offset, size_t len, char *buf, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5, uint8_t b6){
|
||||
static void send_packet(struct usb_device *udev, struct asus_oled_packet *packet, size_t offset, size_t len, char *buf, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5, uint8_t b6) {
|
||||
int retval;
|
||||
int act_len;
|
||||
|
||||
|
@ -294,7 +296,7 @@ static void send_data(struct asus_oled_dev *odev)
|
|||
return;
|
||||
}
|
||||
|
||||
if (odev->pack_mode==PACK_MODE_G1){
|
||||
if (odev->pack_mode == PACK_MODE_G1) {
|
||||
// When sending roll-mode data the display updated only first packet.
|
||||
// I have no idea why, but when static picture is send just before
|
||||
// rolling picture - everything works fine.
|
||||
|
@ -308,7 +310,7 @@ static void send_data(struct asus_oled_dev *odev)
|
|||
send_packets(odev->udev, packet, odev->buf, odev->pic_mode, packet_num);
|
||||
}
|
||||
else
|
||||
if (odev->pack_mode==PACK_MODE_G50){
|
||||
if (odev->pack_mode == PACK_MODE_G50) {
|
||||
send_packets_g50(odev->udev, packet, odev->buf);
|
||||
}
|
||||
|
||||
|
@ -326,7 +328,7 @@ static int append_values(struct asus_oled_dev *odev, uint8_t val, size_t count)
|
|||
x += odev->x_shift;
|
||||
y += odev->y_shift;
|
||||
|
||||
switch(odev->pack_mode)
|
||||
switch (odev->pack_mode)
|
||||
{
|
||||
case PACK_MODE_G1:
|
||||
// i = (x/128)*640 + 127 - x + (y/8)*128;
|
||||
|
@ -377,30 +379,32 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, const char *buf, siz
|
|||
{
|
||||
size_t offs = 0, max_offs;
|
||||
|
||||
if (count < 1) return 0;
|
||||
if (count < 1)
|
||||
return 0;
|
||||
|
||||
if (tolower(buf[0]) == 'b'){
|
||||
if (tolower(buf[0]) == 'b') {
|
||||
// binary mode, set the entire memory
|
||||
|
||||
size_t i;
|
||||
|
||||
odev->buf_size = (odev->dev_width * ASUS_OLED_DISP_HEIGHT) / 8;
|
||||
|
||||
if (odev->buf) kfree(odev->buf);
|
||||
if (odev->buf)
|
||||
kfree(odev->buf);
|
||||
odev->buf = kmalloc(odev->buf_size, GFP_KERNEL);
|
||||
|
||||
memset(odev->buf, 0xff, odev->buf_size);
|
||||
|
||||
for (i=1; i < count && i<=32*32; i++){
|
||||
for (i = 1; i < count && i <= 32 * 32; i++) {
|
||||
odev->buf[i-1] = buf[i];
|
||||
odev->buf_offs = i-1;
|
||||
}
|
||||
|
||||
odev->width=odev->dev_width / 8;
|
||||
odev->height=ASUS_OLED_DISP_HEIGHT;
|
||||
odev->x_shift=0;
|
||||
odev->y_shift=0;
|
||||
odev->last_val=0;
|
||||
odev->width = odev->dev_width / 8;
|
||||
odev->height = ASUS_OLED_DISP_HEIGHT;
|
||||
odev->x_shift = 0;
|
||||
odev->y_shift = 0;
|
||||
odev->last_val = 0;
|
||||
|
||||
send_data(odev);
|
||||
|
||||
|
@ -416,7 +420,7 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, const char *buf, siz
|
|||
goto error_header;
|
||||
}
|
||||
|
||||
switch(tolower(buf[1])) {
|
||||
switch (tolower(buf[1])) {
|
||||
case ASUS_OLED_STATIC:
|
||||
case ASUS_OLED_ROLL:
|
||||
case ASUS_OLED_FLASH:
|
||||
|
@ -432,27 +436,36 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, const char *buf, siz
|
|||
if (buf[i] >= '0' && buf[i] <= '9') {
|
||||
w = 10*w + (buf[i] - '0');
|
||||
|
||||
if (w > ASUS_OLED_MAX_WIDTH) goto error_width;
|
||||
if (w > ASUS_OLED_MAX_WIDTH)
|
||||
goto error_width;
|
||||
}
|
||||
else if (tolower(buf[i]) == 'x') break;
|
||||
else goto error_width;
|
||||
else if (tolower(buf[i]) == 'x')
|
||||
break;
|
||||
else
|
||||
goto error_width;
|
||||
}
|
||||
|
||||
for (++i; i < count; ++i) {
|
||||
if (buf[i] >= '0' && buf[i] <= '9') {
|
||||
h = 10*h + (buf[i] - '0');
|
||||
|
||||
if (h > ASUS_OLED_DISP_HEIGHT) goto error_height;
|
||||
if (h > ASUS_OLED_DISP_HEIGHT)
|
||||
goto error_height;
|
||||
}
|
||||
else if (tolower(buf[i]) == '>') break;
|
||||
else goto error_height;
|
||||
else if (tolower(buf[i]) == '>')
|
||||
break;
|
||||
else
|
||||
goto error_height;
|
||||
}
|
||||
|
||||
if (w < 1 || w > ASUS_OLED_MAX_WIDTH) goto error_width;
|
||||
if (w < 1 || w > ASUS_OLED_MAX_WIDTH)
|
||||
goto error_width;
|
||||
|
||||
if (h < 1 || h > ASUS_OLED_DISP_HEIGHT) goto error_height;
|
||||
if (h < 1 || h > ASUS_OLED_DISP_HEIGHT)
|
||||
goto error_height;
|
||||
|
||||
if (i >= count || buf[i] != '>') goto error_header;
|
||||
if (i >= count || buf[i] != '>')
|
||||
goto error_header;
|
||||
|
||||
offs = i+1;
|
||||
|
||||
|
@ -468,7 +481,8 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, const char *buf, siz
|
|||
|
||||
odev->buf_size = w_mem * h_mem / 8;
|
||||
|
||||
if (odev->buf) kfree(odev->buf);
|
||||
if (odev->buf)
|
||||
kfree(odev->buf);
|
||||
odev->buf = kmalloc(odev->buf_size, GFP_KERNEL);
|
||||
|
||||
if (odev->buf == NULL) {
|
||||
|
@ -505,23 +519,30 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, const char *buf, siz
|
|||
int ret;
|
||||
|
||||
if (buf[offs] == '1' || buf[offs] == '#') {
|
||||
if ( (ret = append_values(odev, 1, 1)) < 0) return ret;
|
||||
ret = append_values(odev, 1, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
else if (buf[offs] == '0' || buf[offs] == ' ') {
|
||||
if ( (ret = append_values(odev, 0, 1)) < 0) return ret;
|
||||
ret = append_values(odev, 0, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
else if (buf[offs] == '\n') {
|
||||
// New line detected. Lets assume, that all characters till the end of the
|
||||
// line were equal to the last character in this line.
|
||||
if (odev->buf_offs % odev->width != 0)
|
||||
if ( (ret = append_values(odev, odev->last_val,
|
||||
odev->width - (odev->buf_offs % odev->width))) < 0) return ret;
|
||||
ret = append_values(odev, odev->last_val,
|
||||
odev->width - (odev->buf_offs % odev->width));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
offs++;
|
||||
}
|
||||
|
||||
if (odev->buf_offs >= max_offs) send_data(odev);
|
||||
if (odev->buf_offs >= max_offs)
|
||||
send_data(odev);
|
||||
|
||||
return count;
|
||||
|
||||
|
@ -566,9 +587,9 @@ static int asus_oled_probe(struct usb_interface *interface, const struct usb_dev
|
|||
uint16_t dev_width = 0;
|
||||
oled_pack_mode_t pack_mode = PACK_MODE_LAST;
|
||||
const struct oled_dev_desc_str * dev_desc = oled_dev_desc_table;
|
||||
const char *desc = 0;
|
||||
const char *desc = NULL;
|
||||
|
||||
if (id == 0) {
|
||||
if (!id) {
|
||||
// Even possible? Just to make sure...
|
||||
dev_err(&interface->dev, "No usb_device_id provided!\n");
|
||||
return -ENODEV;
|
||||
|
@ -586,7 +607,7 @@ static int asus_oled_probe(struct usb_interface *interface, const struct usb_dev
|
|||
}
|
||||
}
|
||||
|
||||
if ( !desc || dev_width < 1 || pack_mode == PACK_MODE_LAST) {
|
||||
if (!desc || dev_width < 1 || pack_mode == PACK_MODE_LAST) {
|
||||
dev_err(&interface->dev, "Missing or incomplete device description!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
@ -611,20 +632,20 @@ static int asus_oled_probe(struct usb_interface *interface, const struct usb_dev
|
|||
odev->last_val = 0;
|
||||
odev->buf = NULL;
|
||||
odev->enabled = 1;
|
||||
odev->dev = 0;
|
||||
odev->dev = NULL;
|
||||
|
||||
usb_set_intfdata (interface, odev);
|
||||
usb_set_intfdata(interface, odev);
|
||||
|
||||
if ((retval = device_create_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(enabled)))) {
|
||||
retval = device_create_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(enabled));
|
||||
if (retval)
|
||||
goto err_files;
|
||||
}
|
||||
|
||||
if ((retval = device_create_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(picture)))) {
|
||||
retval = device_create_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(picture));
|
||||
if (retval)
|
||||
goto err_files;
|
||||
}
|
||||
|
||||
odev->dev = device_create(oled_class, &interface->dev, MKDEV(0,0),
|
||||
NULL,"oled_%d", ++oled_num);
|
||||
odev->dev = device_create(oled_class, &interface->dev, MKDEV(0, 0),
|
||||
NULL, "oled_%d", ++oled_num);
|
||||
|
||||
if (IS_ERR(odev->dev)) {
|
||||
retval = PTR_ERR(odev->dev);
|
||||
|
@ -633,13 +654,13 @@ static int asus_oled_probe(struct usb_interface *interface, const struct usb_dev
|
|||
|
||||
dev_set_drvdata(odev->dev, odev);
|
||||
|
||||
if ( (retval = device_create_file(odev->dev, &dev_attr_enabled))) {
|
||||
retval = device_create_file(odev->dev, &dev_attr_enabled);
|
||||
if (retval)
|
||||
goto err_class_enabled;
|
||||
}
|
||||
|
||||
if ( (retval = device_create_file(odev->dev, &dev_attr_picture))) {
|
||||
retval = device_create_file(odev->dev, &dev_attr_picture);
|
||||
if (retval)
|
||||
goto err_class_picture;
|
||||
}
|
||||
|
||||
dev_info(&interface->dev, "Attached Asus OLED device: %s [width %u, pack_mode %d]\n", desc, odev->dev_width, odev->pack_mode);
|
||||
|
||||
|
@ -659,7 +680,7 @@ err_files:
|
|||
device_remove_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(enabled));
|
||||
device_remove_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(picture));
|
||||
|
||||
usb_set_intfdata (interface, NULL);
|
||||
usb_set_intfdata(interface, NULL);
|
||||
usb_put_dev(odev->udev);
|
||||
kfree(odev);
|
||||
|
||||
|
@ -670,19 +691,20 @@ static void asus_oled_disconnect(struct usb_interface *interface)
|
|||
{
|
||||
struct asus_oled_dev *odev;
|
||||
|
||||
odev = usb_get_intfdata (interface);
|
||||
usb_set_intfdata (interface, NULL);
|
||||
odev = usb_get_intfdata(interface);
|
||||
usb_set_intfdata(interface, NULL);
|
||||
|
||||
device_remove_file(odev->dev, &dev_attr_picture);
|
||||
device_remove_file(odev->dev, &dev_attr_enabled);
|
||||
device_unregister(odev->dev);
|
||||
|
||||
device_remove_file(&interface->dev, & ASUS_OLED_DEVICE_ATTR(picture));
|
||||
device_remove_file(&interface->dev, & ASUS_OLED_DEVICE_ATTR(enabled));
|
||||
device_remove_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(picture));
|
||||
device_remove_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(enabled));
|
||||
|
||||
usb_put_dev(odev->udev);
|
||||
|
||||
if (odev->buf) kfree(odev->buf);
|
||||
if (odev->buf)
|
||||
kfree(odev->buf);
|
||||
|
||||
kfree(odev);
|
||||
|
||||
|
@ -713,7 +735,8 @@ static int __init asus_oled_init(void)
|
|||
return PTR_ERR(oled_class);
|
||||
}
|
||||
|
||||
if ((retval = class_create_file(oled_class, &class_attr_version))) {
|
||||
retval = class_create_file(oled_class, &class_attr_version);
|
||||
if (retval) {
|
||||
err("Error creating class version file");
|
||||
goto error;
|
||||
}
|
||||
|
@ -740,6 +763,6 @@ static void __exit asus_oled_exit(void)
|
|||
usb_deregister(&oled_driver);
|
||||
}
|
||||
|
||||
module_init (asus_oled_init);
|
||||
module_exit (asus_oled_exit);
|
||||
module_init(asus_oled_init);
|
||||
module_exit(asus_oled_exit);
|
||||
|
||||
|
|
|
@ -1,2 +1,7 @@
|
|||
rewrite the driver to use the proper in-kernel wireless stack
|
||||
instead of using its own.
|
||||
Fix the mac80211 port of at76_usb (the proper in-kernel wireless
|
||||
stack) and get it included to the mainline. Patches available here:
|
||||
|
||||
http://git.kernel.org/?p=linux/kernel/git/linville/wireless-legacy.git;a=shortlog;h=at76
|
||||
|
||||
Contact Kalle Valo <kalle.valo@iki.fi> and linux-wireless list
|
||||
<linux-wireless@vger.kernel.org> for more information.
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#include <net/ieee80211_radiotap.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/leds.h>
|
||||
#include <net/ieee80211.h>
|
||||
#include <linux/ieee80211.h>
|
||||
|
||||
#include "at76_usb.h"
|
||||
|
||||
|
@ -1727,12 +1727,12 @@ static int at76_assoc_req(struct at76_priv *priv, struct bss_info *bss)
|
|||
|
||||
/* write TLV data elements */
|
||||
|
||||
ie->id = MFIE_TYPE_SSID;
|
||||
ie->id = WLAN_EID_SSID;
|
||||
ie->len = bss->ssid_len;
|
||||
memcpy(ie->data, bss->ssid, bss->ssid_len);
|
||||
next_ie(&ie);
|
||||
|
||||
ie->id = MFIE_TYPE_RATES;
|
||||
ie->id = WLAN_EID_SUPP_RATES;
|
||||
ie->len = sizeof(hw_rates);
|
||||
memcpy(ie->data, hw_rates, sizeof(hw_rates));
|
||||
next_ie(&ie); /* ie points behind the supp_rates field */
|
||||
|
@ -4397,7 +4397,7 @@ static void at76_rx_mgmt_beacon(struct at76_priv *priv,
|
|||
|
||||
switch (ie->id) {
|
||||
|
||||
case MFIE_TYPE_SSID:
|
||||
case WLAN_EID_SSID:
|
||||
if (have_ssid)
|
||||
break;
|
||||
|
||||
|
@ -4420,7 +4420,7 @@ static void at76_rx_mgmt_beacon(struct at76_priv *priv,
|
|||
have_ssid = 1;
|
||||
break;
|
||||
|
||||
case MFIE_TYPE_RATES:
|
||||
case WLAN_EID_SUPP_RATES:
|
||||
if (have_rates)
|
||||
break;
|
||||
|
||||
|
@ -4433,7 +4433,7 @@ static void at76_rx_mgmt_beacon(struct at76_priv *priv,
|
|||
hex2str(ie->data, ie->len));
|
||||
break;
|
||||
|
||||
case MFIE_TYPE_DS_SET:
|
||||
case WLAN_EID_DS_PARAMS:
|
||||
if (have_channel)
|
||||
break;
|
||||
|
||||
|
@ -4443,9 +4443,9 @@ static void at76_rx_mgmt_beacon(struct at76_priv *priv,
|
|||
priv->netdev->name, match->channel);
|
||||
break;
|
||||
|
||||
case MFIE_TYPE_CF_SET:
|
||||
case MFIE_TYPE_TIM:
|
||||
case MFIE_TYPE_IBSS_SET:
|
||||
case WLAN_EID_CF_PARAMS:
|
||||
case WLAN_EID_TIM:
|
||||
case WLAN_EID_IBSS_PARAMS:
|
||||
default:
|
||||
at76_dbg(DBG_RX_BEACON, "%s: beacon IE id %d len %d %s",
|
||||
priv->netdev->name, ie->id, ie->len,
|
||||
|
@ -5370,8 +5370,7 @@ static void at76_delete_device(struct at76_priv *priv)
|
|||
|
||||
at76_dbg(DBG_PROC_ENTRY, "%s: unlinked urbs", __func__);
|
||||
|
||||
if (priv->rx_skb)
|
||||
kfree_skb(priv->rx_skb);
|
||||
kfree_skb(priv->rx_skb);
|
||||
|
||||
at76_free_bss_list(priv);
|
||||
del_timer_sync(&priv->bss_list_timer);
|
||||
|
|
|
@ -22,6 +22,93 @@
|
|||
#ifndef _AT76_USB_H
|
||||
#define _AT76_USB_H
|
||||
|
||||
/*
|
||||
* ieee80211 definitions copied from net/ieee80211.h
|
||||
*/
|
||||
|
||||
#define WEP_KEY_LEN 13
|
||||
#define WEP_KEYS 4
|
||||
|
||||
#define IEEE80211_DATA_LEN 2304
|
||||
/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
|
||||
6.2.1.1.2.
|
||||
|
||||
The figure in section 7.1.2 suggests a body size of up to 2312
|
||||
bytes is allowed, which is a bit confusing, I suspect this
|
||||
represents the 2304 bytes of real data, plus a possible 8 bytes of
|
||||
WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
|
||||
|
||||
#define IEEE80211_1ADDR_LEN 10
|
||||
#define IEEE80211_2ADDR_LEN 16
|
||||
#define IEEE80211_3ADDR_LEN 24
|
||||
#define IEEE80211_4ADDR_LEN 30
|
||||
#define IEEE80211_FCS_LEN 4
|
||||
#define IEEE80211_HLEN (IEEE80211_4ADDR_LEN)
|
||||
#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN)
|
||||
|
||||
#define MIN_FRAG_THRESHOLD 256U
|
||||
#define MAX_FRAG_THRESHOLD 2346U
|
||||
|
||||
struct ieee80211_info_element {
|
||||
u8 id;
|
||||
u8 len;
|
||||
u8 data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct ieee80211_hdr_3addr {
|
||||
__le16 frame_ctl;
|
||||
__le16 duration_id;
|
||||
u8 addr1[ETH_ALEN];
|
||||
u8 addr2[ETH_ALEN];
|
||||
u8 addr3[ETH_ALEN];
|
||||
__le16 seq_ctl;
|
||||
u8 payload[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct ieee80211_auth {
|
||||
struct ieee80211_hdr_3addr header;
|
||||
__le16 algorithm;
|
||||
__le16 transaction;
|
||||
__le16 status;
|
||||
/* challenge */
|
||||
struct ieee80211_info_element info_element[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct ieee80211_assoc_request {
|
||||
struct ieee80211_hdr_3addr header;
|
||||
__le16 capability;
|
||||
__le16 listen_interval;
|
||||
/* SSID, supported rates, RSN */
|
||||
struct ieee80211_info_element info_element[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct ieee80211_probe_response {
|
||||
struct ieee80211_hdr_3addr header;
|
||||
__le32 time_stamp[2];
|
||||
__le16 beacon_interval;
|
||||
__le16 capability;
|
||||
/* SSID, supported rates, FH params, DS params,
|
||||
* CF params, IBSS params, TIM (if beacon), RSN */
|
||||
struct ieee80211_info_element info_element[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Alias beacon for probe_response */
|
||||
#define ieee80211_beacon ieee80211_probe_response
|
||||
|
||||
struct ieee80211_assoc_response {
|
||||
struct ieee80211_hdr_3addr header;
|
||||
__le16 capability;
|
||||
__le16 status;
|
||||
__le16 aid;
|
||||
/* supported rates */
|
||||
struct ieee80211_info_element info_element[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct ieee80211_disassoc {
|
||||
struct ieee80211_hdr_3addr header;
|
||||
__le16 reason;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Board types */
|
||||
enum board_type {
|
||||
BOARD_503_ISL3861 = 1,
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
config B3DFG
|
||||
tristate "Brontes 3d Frame Framegrabber"
|
||||
default n
|
||||
---help---
|
||||
This driver provides support for the Brontes 3d Framegrabber
|
||||
PCI card.
|
||||
|
||||
To compile this driver as a module, choose M here. The module
|
||||
will be called b3dfg.
|
|
@ -0,0 +1 @@
|
|||
obj-$(CONFIG_B3DFG) += b3dfg.o
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
- queue/wait buffer presents filltime results for each frame?
|
||||
- counting of dropped frames
|
||||
- review endianness
|
File diff suppressed because it is too large
Load Diff
|
@ -6,6 +6,13 @@ config COMEDI
|
|||
Enable support a wide range of data acquisition devices
|
||||
for Linux.
|
||||
|
||||
config COMEDI_DEBUG
|
||||
bool "Comedi debugging"
|
||||
depends on COMEDI != n
|
||||
help
|
||||
This is an option for use by developers; most people should
|
||||
say N here. This enables comedi core and driver debugging.
|
||||
|
||||
config COMEDI_RT
|
||||
tristate "Comedi Real-time support"
|
||||
depends on COMEDI && RT
|
||||
|
@ -20,6 +27,13 @@ config COMEDI_PCI_DRIVERS
|
|||
---help---
|
||||
Enable lots of comedi PCI drivers to be built
|
||||
|
||||
config COMEDI_PCMCIA_DRIVERS
|
||||
tristate "Comedi PCMCIA drivers"
|
||||
depends on COMEDI && PCMCIAI
|
||||
default N
|
||||
---help---
|
||||
Enable lots of comedi PCMCIA drivers to be built
|
||||
|
||||
config COMEDI_USB_DRIVERS
|
||||
tristate "Comedi USB drivers"
|
||||
depends on COMEDI && USB
|
||||
|
|
|
@ -57,9 +57,6 @@ extern "C" {
|
|||
/* max length of device and driver names */
|
||||
#define COMEDI_NAMELEN 20
|
||||
|
||||
typedef unsigned int lsampl_t;
|
||||
typedef unsigned short sampl_t;
|
||||
|
||||
/* packs and unpacks a channel/range number */
|
||||
|
||||
#define CR_PACK(chan, rng, aref) ((((aref)&0x3)<<24) | (((rng)&0xff)<<16) | (chan))
|
||||
|
@ -261,10 +258,11 @@ enum configuration_ids {
|
|||
INSN_CONFIG_GET_CLOCK_SRC = 2004, /* Get master clock source */
|
||||
INSN_CONFIG_SET_OTHER_SRC = 2005, /* Set other source */
|
||||
/* INSN_CONFIG_GET_OTHER_SRC = 2006,*/ /* Get other source */
|
||||
INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE, /* Get size in bytes of
|
||||
subdevice's on-board fifos
|
||||
used during streaming
|
||||
input/output */
|
||||
INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE = 2006, /* Get size in bytes of
|
||||
subdevice's on-board
|
||||
fifos used during
|
||||
streaming
|
||||
input/output */
|
||||
INSN_CONFIG_SET_COUNTER_MODE = 4097,
|
||||
INSN_CONFIG_8254_SET_MODE = INSN_CONFIG_SET_COUNTER_MODE, /* deprecated */
|
||||
INSN_CONFIG_8254_READ_STATUS = 4098,
|
||||
|
@ -293,45 +291,32 @@ enum comedi_support_level {
|
|||
/* ioctls */
|
||||
|
||||
#define CIO 'd'
|
||||
#define COMEDI_DEVCONFIG _IOW(CIO, 0, comedi_devconfig)
|
||||
#define COMEDI_DEVINFO _IOR(CIO, 1, comedi_devinfo)
|
||||
#define COMEDI_SUBDINFO _IOR(CIO, 2, comedi_subdinfo)
|
||||
#define COMEDI_CHANINFO _IOR(CIO, 3, comedi_chaninfo)
|
||||
#define COMEDI_DEVCONFIG _IOW(CIO, 0, struct comedi_devconfig)
|
||||
#define COMEDI_DEVINFO _IOR(CIO, 1, struct comedi_devinfo)
|
||||
#define COMEDI_SUBDINFO _IOR(CIO, 2, struct comedi_subdinfo)
|
||||
#define COMEDI_CHANINFO _IOR(CIO, 3, struct comedi_chaninfo)
|
||||
#define COMEDI_TRIG _IOWR(CIO, 4, comedi_trig)
|
||||
#define COMEDI_LOCK _IO(CIO, 5)
|
||||
#define COMEDI_UNLOCK _IO(CIO, 6)
|
||||
#define COMEDI_CANCEL _IO(CIO, 7)
|
||||
#define COMEDI_RANGEINFO _IOR(CIO, 8, comedi_rangeinfo)
|
||||
#define COMEDI_CMD _IOR(CIO, 9, comedi_cmd)
|
||||
#define COMEDI_CMDTEST _IOR(CIO, 10, comedi_cmd)
|
||||
#define COMEDI_INSNLIST _IOR(CIO, 11, comedi_insnlist)
|
||||
#define COMEDI_INSN _IOR(CIO, 12, comedi_insn)
|
||||
#define COMEDI_BUFCONFIG _IOR(CIO, 13, comedi_bufconfig)
|
||||
#define COMEDI_BUFINFO _IOWR(CIO, 14, comedi_bufinfo)
|
||||
#define COMEDI_RANGEINFO _IOR(CIO, 8, struct comedi_rangeinfo)
|
||||
#define COMEDI_CMD _IOR(CIO, 9, struct comedi_cmd)
|
||||
#define COMEDI_CMDTEST _IOR(CIO, 10, struct comedi_cmd)
|
||||
#define COMEDI_INSNLIST _IOR(CIO, 11, struct comedi_insnlist)
|
||||
#define COMEDI_INSN _IOR(CIO, 12, struct comedi_insn)
|
||||
#define COMEDI_BUFCONFIG _IOR(CIO, 13, struct comedi_bufconfig)
|
||||
#define COMEDI_BUFINFO _IOWR(CIO, 14, struct comedi_bufinfo)
|
||||
#define COMEDI_POLL _IO(CIO, 15)
|
||||
|
||||
/* structures */
|
||||
|
||||
typedef struct comedi_trig_struct comedi_trig;
|
||||
typedef struct comedi_cmd_struct comedi_cmd;
|
||||
typedef struct comedi_insn_struct comedi_insn;
|
||||
typedef struct comedi_insnlist_struct comedi_insnlist;
|
||||
typedef struct comedi_chaninfo_struct comedi_chaninfo;
|
||||
typedef struct comedi_subdinfo_struct comedi_subdinfo;
|
||||
typedef struct comedi_devinfo_struct comedi_devinfo;
|
||||
typedef struct comedi_devconfig_struct comedi_devconfig;
|
||||
typedef struct comedi_rangeinfo_struct comedi_rangeinfo;
|
||||
typedef struct comedi_krange_struct comedi_krange;
|
||||
typedef struct comedi_bufconfig_struct comedi_bufconfig;
|
||||
typedef struct comedi_bufinfo_struct comedi_bufinfo;
|
||||
|
||||
struct comedi_trig_struct {
|
||||
struct comedi_trig {
|
||||
unsigned int subdev; /* subdevice */
|
||||
unsigned int mode; /* mode */
|
||||
unsigned int flags;
|
||||
unsigned int n_chan; /* number of channels */
|
||||
unsigned int *chanlist; /* channel/range list */
|
||||
sampl_t *data; /* data list, size depends on subd flags */
|
||||
short *data; /* data list, size depends on subd flags */
|
||||
unsigned int n; /* number of scans */
|
||||
unsigned int trigsrc;
|
||||
unsigned int trigvar;
|
||||
|
@ -340,21 +325,21 @@ struct comedi_trig_struct {
|
|||
unsigned int unused[3];
|
||||
};
|
||||
|
||||
struct comedi_insn_struct {
|
||||
struct comedi_insn {
|
||||
unsigned int insn;
|
||||
unsigned int n;
|
||||
lsampl_t *data;
|
||||
unsigned int *data;
|
||||
unsigned int subdev;
|
||||
unsigned int chanspec;
|
||||
unsigned int unused[3];
|
||||
};
|
||||
|
||||
struct comedi_insnlist_struct {
|
||||
struct comedi_insnlist {
|
||||
unsigned int n_insns;
|
||||
comedi_insn *insns;
|
||||
struct comedi_insn *insns;
|
||||
};
|
||||
|
||||
struct comedi_cmd_struct {
|
||||
struct comedi_cmd {
|
||||
unsigned int subdev;
|
||||
unsigned int flags;
|
||||
|
||||
|
@ -376,37 +361,37 @@ struct comedi_cmd_struct {
|
|||
unsigned int *chanlist; /* channel/range list */
|
||||
unsigned int chanlist_len;
|
||||
|
||||
sampl_t *data; /* data list, size depends on subd flags */
|
||||
short *data; /* data list, size depends on subd flags */
|
||||
unsigned int data_len;
|
||||
};
|
||||
|
||||
struct comedi_chaninfo_struct {
|
||||
struct comedi_chaninfo {
|
||||
unsigned int subdev;
|
||||
lsampl_t *maxdata_list;
|
||||
unsigned int *maxdata_list;
|
||||
unsigned int *flaglist;
|
||||
unsigned int *rangelist;
|
||||
unsigned int unused[4];
|
||||
};
|
||||
|
||||
struct comedi_rangeinfo_struct {
|
||||
struct comedi_rangeinfo {
|
||||
unsigned int range_type;
|
||||
void *range_ptr;
|
||||
};
|
||||
|
||||
struct comedi_krange_struct {
|
||||
struct comedi_krange {
|
||||
int min; /* fixed point, multiply by 1e-6 */
|
||||
int max; /* fixed point, multiply by 1e-6 */
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
|
||||
struct comedi_subdinfo_struct {
|
||||
struct comedi_subdinfo {
|
||||
unsigned int type;
|
||||
unsigned int n_chan;
|
||||
unsigned int subd_flags;
|
||||
unsigned int timer_type;
|
||||
unsigned int len_chanlist;
|
||||
lsampl_t maxdata;
|
||||
unsigned int maxdata;
|
||||
unsigned int flags; /* channel flags */
|
||||
unsigned int range_type; /* lookup in kernel */
|
||||
unsigned int settling_time_0;
|
||||
|
@ -414,7 +399,7 @@ struct comedi_subdinfo_struct {
|
|||
unsigned int unused[8];
|
||||
};
|
||||
|
||||
struct comedi_devinfo_struct {
|
||||
struct comedi_devinfo {
|
||||
unsigned int version_code;
|
||||
unsigned int n_subdevs;
|
||||
char driver_name[COMEDI_NAMELEN];
|
||||
|
@ -424,12 +409,12 @@ struct comedi_devinfo_struct {
|
|||
int unused[30];
|
||||
};
|
||||
|
||||
struct comedi_devconfig_struct {
|
||||
struct comedi_devconfig {
|
||||
char board_name[COMEDI_NAMELEN];
|
||||
int options[COMEDI_NDEVCONFOPTS];
|
||||
};
|
||||
|
||||
struct comedi_bufconfig_struct {
|
||||
struct comedi_bufconfig {
|
||||
unsigned int subdevice;
|
||||
unsigned int flags;
|
||||
|
||||
|
@ -439,7 +424,7 @@ struct comedi_bufconfig_struct {
|
|||
unsigned int unused[4];
|
||||
};
|
||||
|
||||
struct comedi_bufinfo_struct {
|
||||
struct comedi_bufinfo {
|
||||
unsigned int subdevice;
|
||||
unsigned int bytes_read;
|
||||
|
||||
|
|
|
@ -37,31 +37,31 @@
|
|||
#include <linux/ioctl32.h> /* for (un)register_ioctl32_conversion */
|
||||
#endif
|
||||
|
||||
#define COMEDI32_CHANINFO _IOR(CIO,3,comedi32_chaninfo)
|
||||
#define COMEDI32_RANGEINFO _IOR(CIO,8,comedi32_rangeinfo)
|
||||
#define COMEDI32_CHANINFO _IOR(CIO, 3, struct comedi32_chaninfo_struct)
|
||||
#define COMEDI32_RANGEINFO _IOR(CIO, 8, struct comedi32_rangeinfo_struct)
|
||||
/* N.B. COMEDI32_CMD and COMEDI_CMD ought to use _IOWR, not _IOR.
|
||||
* It's too late to change it now, but it only affects the command number. */
|
||||
#define COMEDI32_CMD _IOR(CIO,9,comedi32_cmd)
|
||||
#define COMEDI32_CMD _IOR(CIO, 9, struct comedi32_cmd_struct)
|
||||
/* N.B. COMEDI32_CMDTEST and COMEDI_CMDTEST ought to use _IOWR, not _IOR.
|
||||
* It's too late to change it now, but it only affects the command number. */
|
||||
#define COMEDI32_CMDTEST _IOR(CIO,10,comedi32_cmd)
|
||||
#define COMEDI32_INSNLIST _IOR(CIO,11,comedi32_insnlist)
|
||||
#define COMEDI32_INSN _IOR(CIO,12,comedi32_insn)
|
||||
#define COMEDI32_CMDTEST _IOR(CIO, 10, struct comedi32_cmd_struct)
|
||||
#define COMEDI32_INSNLIST _IOR(CIO, 11, struct comedi32_insnlist_struct)
|
||||
#define COMEDI32_INSN _IOR(CIO, 12, struct comedi32_insn_struct)
|
||||
|
||||
typedef struct comedi32_chaninfo_struct {
|
||||
struct comedi32_chaninfo_struct {
|
||||
unsigned int subdev;
|
||||
compat_uptr_t maxdata_list; /* 32-bit 'lsampl_t *' */
|
||||
compat_uptr_t maxdata_list; /* 32-bit 'unsigned int *' */
|
||||
compat_uptr_t flaglist; /* 32-bit 'unsigned int *' */
|
||||
compat_uptr_t rangelist; /* 32-bit 'unsigned int *' */
|
||||
unsigned int unused[4];
|
||||
} comedi32_chaninfo;
|
||||
};
|
||||
|
||||
typedef struct comedi32_rangeinfo_struct {
|
||||
struct comedi32_rangeinfo_struct {
|
||||
unsigned int range_type;
|
||||
compat_uptr_t range_ptr; /* 32-bit 'void *' */
|
||||
} comedi32_rangeinfo;
|
||||
};
|
||||
|
||||
typedef struct comedi32_cmd_struct {
|
||||
struct comedi32_cmd_struct {
|
||||
unsigned int subdev;
|
||||
unsigned int flags;
|
||||
unsigned int start_src;
|
||||
|
@ -76,37 +76,36 @@ typedef struct comedi32_cmd_struct {
|
|||
unsigned int stop_arg;
|
||||
compat_uptr_t chanlist; /* 32-bit 'unsigned int *' */
|
||||
unsigned int chanlist_len;
|
||||
compat_uptr_t data; /* 32-bit 'sampl_t *' */
|
||||
compat_uptr_t data; /* 32-bit 'short *' */
|
||||
unsigned int data_len;
|
||||
} comedi32_cmd;
|
||||
};
|
||||
|
||||
typedef struct comedi32_insn_struct {
|
||||
struct comedi32_insn_struct {
|
||||
unsigned int insn;
|
||||
unsigned int n;
|
||||
compat_uptr_t data; /* 32-bit 'lsampl_t *' */
|
||||
compat_uptr_t data; /* 32-bit 'unsigned int *' */
|
||||
unsigned int subdev;
|
||||
unsigned int chanspec;
|
||||
unsigned int unused[3];
|
||||
} comedi32_insn;
|
||||
};
|
||||
|
||||
typedef struct comedi32_insnlist_struct {
|
||||
struct comedi32_insnlist_struct {
|
||||
unsigned int n_insns;
|
||||
compat_uptr_t insns; /* 32-bit 'comedi_insn *' */
|
||||
} comedi32_insnlist;
|
||||
compat_uptr_t insns; /* 32-bit 'struct comedi_insn *' */
|
||||
};
|
||||
|
||||
/* Handle translated ioctl. */
|
||||
static int translated_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
if (!file->f_op) {
|
||||
if (!file->f_op)
|
||||
return -ENOTTY;
|
||||
}
|
||||
|
||||
#ifdef HAVE_UNLOCKED_IOCTL
|
||||
if (file->f_op->unlocked_ioctl) {
|
||||
int rc = (int)(*file->f_op->unlocked_ioctl)(file, cmd, arg);
|
||||
if (rc == -ENOIOCTLCMD) {
|
||||
if (rc == -ENOIOCTLCMD)
|
||||
rc = -ENOTTY;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
@ -124,8 +123,8 @@ static int translated_ioctl(struct file *file, unsigned int cmd,
|
|||
/* Handle 32-bit COMEDI_CHANINFO ioctl. */
|
||||
static int compat_chaninfo(struct file *file, unsigned long arg)
|
||||
{
|
||||
comedi_chaninfo __user *chaninfo;
|
||||
comedi32_chaninfo __user *chaninfo32;
|
||||
struct comedi_chaninfo __user *chaninfo;
|
||||
struct comedi32_chaninfo_struct __user *chaninfo32;
|
||||
int err;
|
||||
union {
|
||||
unsigned int uint;
|
||||
|
@ -150,9 +149,8 @@ static int compat_chaninfo(struct file *file, unsigned long arg)
|
|||
err |= __put_user(compat_ptr(temp.uptr), &chaninfo->flaglist);
|
||||
err |= __get_user(temp.uptr, &chaninfo32->rangelist);
|
||||
err |= __put_user(compat_ptr(temp.uptr), &chaninfo->rangelist);
|
||||
if (err) {
|
||||
if (err)
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return translated_ioctl(file, COMEDI_CHANINFO, (unsigned long)chaninfo);
|
||||
}
|
||||
|
@ -160,8 +158,8 @@ static int compat_chaninfo(struct file *file, unsigned long arg)
|
|||
/* Handle 32-bit COMEDI_RANGEINFO ioctl. */
|
||||
static int compat_rangeinfo(struct file *file, unsigned long arg)
|
||||
{
|
||||
comedi_rangeinfo __user *rangeinfo;
|
||||
comedi32_rangeinfo __user *rangeinfo32;
|
||||
struct comedi_rangeinfo __user *rangeinfo;
|
||||
struct comedi32_rangeinfo_struct __user *rangeinfo32;
|
||||
int err;
|
||||
union {
|
||||
unsigned int uint;
|
||||
|
@ -182,17 +180,16 @@ static int compat_rangeinfo(struct file *file, unsigned long arg)
|
|||
err |= __put_user(temp.uint, &rangeinfo->range_type);
|
||||
err |= __get_user(temp.uptr, &rangeinfo32->range_ptr);
|
||||
err |= __put_user(compat_ptr(temp.uptr), &rangeinfo->range_ptr);
|
||||
if (err) {
|
||||
if (err)
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return translated_ioctl(file, COMEDI_RANGEINFO,
|
||||
(unsigned long)rangeinfo);
|
||||
}
|
||||
|
||||
/* Copy 32-bit cmd structure to native cmd structure. */
|
||||
static int get_compat_cmd(comedi_cmd __user *cmd,
|
||||
comedi32_cmd __user *cmd32)
|
||||
static int get_compat_cmd(struct comedi_cmd __user *cmd,
|
||||
struct comedi32_cmd_struct __user *cmd32)
|
||||
{
|
||||
int err;
|
||||
union {
|
||||
|
@ -242,7 +239,7 @@ static int get_compat_cmd(comedi_cmd __user *cmd,
|
|||
}
|
||||
|
||||
/* Copy native cmd structure to 32-bit cmd structure. */
|
||||
static int put_compat_cmd(comedi32_cmd __user *cmd32, comedi_cmd __user *cmd)
|
||||
static int put_compat_cmd(struct comedi32_cmd_struct __user *cmd32, struct comedi_cmd __user *cmd)
|
||||
{
|
||||
int err;
|
||||
unsigned int temp;
|
||||
|
@ -292,17 +289,16 @@ static int put_compat_cmd(comedi32_cmd __user *cmd32, comedi_cmd __user *cmd)
|
|||
/* Handle 32-bit COMEDI_CMD ioctl. */
|
||||
static int compat_cmd(struct file *file, unsigned long arg)
|
||||
{
|
||||
comedi_cmd __user *cmd;
|
||||
comedi32_cmd __user *cmd32;
|
||||
struct comedi_cmd __user *cmd;
|
||||
struct comedi32_cmd_struct __user *cmd32;
|
||||
int rc;
|
||||
|
||||
cmd32 = compat_ptr(arg);
|
||||
cmd = compat_alloc_user_space(sizeof(*cmd));
|
||||
|
||||
rc = get_compat_cmd(cmd, cmd32);
|
||||
if (rc) {
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
return translated_ioctl(file, COMEDI_CMD, (unsigned long)cmd);
|
||||
}
|
||||
|
@ -310,33 +306,31 @@ static int compat_cmd(struct file *file, unsigned long arg)
|
|||
/* Handle 32-bit COMEDI_CMDTEST ioctl. */
|
||||
static int compat_cmdtest(struct file *file, unsigned long arg)
|
||||
{
|
||||
comedi_cmd __user *cmd;
|
||||
comedi32_cmd __user *cmd32;
|
||||
struct comedi_cmd __user *cmd;
|
||||
struct comedi32_cmd_struct __user *cmd32;
|
||||
int rc, err;
|
||||
|
||||
cmd32 = compat_ptr(arg);
|
||||
cmd = compat_alloc_user_space(sizeof(*cmd));
|
||||
|
||||
rc = get_compat_cmd(cmd, cmd32);
|
||||
if (rc) {
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = translated_ioctl(file, COMEDI_CMDTEST, (unsigned long)cmd);
|
||||
if (rc < 0) {
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
|
||||
err = put_compat_cmd(cmd32, cmd);
|
||||
if (err) {
|
||||
if (err)
|
||||
rc = err;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Copy 32-bit insn structure to native insn structure. */
|
||||
static int get_compat_insn(comedi_insn __user *insn,
|
||||
comedi32_insn __user *insn32)
|
||||
static int get_compat_insn(struct comedi_insn __user *insn,
|
||||
struct comedi32_insn_struct __user *insn32)
|
||||
{
|
||||
int err;
|
||||
union {
|
||||
|
@ -347,9 +341,9 @@ static int get_compat_insn(comedi_insn __user *insn,
|
|||
/* Copy insn structure. Ignore the unused members. */
|
||||
err = 0;
|
||||
if (!access_ok(VERIFY_READ, insn32, sizeof(*insn32))
|
||||
|| !access_ok(VERIFY_WRITE, insn, sizeof(*insn))) {
|
||||
|| !access_ok(VERIFY_WRITE, insn, sizeof(*insn)))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
err |= __get_user(temp.uint, &insn32->insn);
|
||||
err |= __put_user(temp.uint, &insn->insn);
|
||||
err |= __get_user(temp.uint, &insn32->n);
|
||||
|
@ -367,11 +361,11 @@ static int get_compat_insn(comedi_insn __user *insn,
|
|||
static int compat_insnlist(struct file *file, unsigned long arg)
|
||||
{
|
||||
struct combined_insnlist {
|
||||
comedi_insnlist insnlist;
|
||||
comedi_insn insn[1];
|
||||
struct comedi_insnlist insnlist;
|
||||
struct comedi_insn insn[1];
|
||||
} __user *s;
|
||||
comedi32_insnlist __user *insnlist32;
|
||||
comedi32_insn __user *insn32;
|
||||
struct comedi32_insnlist_struct __user *insnlist32;
|
||||
struct comedi32_insn_struct __user *insn32;
|
||||
compat_uptr_t uptr;
|
||||
unsigned int n_insns, n;
|
||||
int err, rc;
|
||||
|
@ -386,9 +380,8 @@ static int compat_insnlist(struct file *file, unsigned long arg)
|
|||
err |= __get_user(n_insns, &insnlist32->n_insns);
|
||||
err |= __get_user(uptr, &insnlist32->insns);
|
||||
insn32 = compat_ptr(uptr);
|
||||
if (err) {
|
||||
if (err)
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
/* Allocate user memory to copy insnlist and insns into. */
|
||||
s = compat_alloc_user_space(offsetof(struct combined_insnlist,
|
||||
|
@ -400,16 +393,14 @@ static int compat_insnlist(struct file *file, unsigned long arg)
|
|||
}
|
||||
err |= __put_user(n_insns, &s->insnlist.n_insns);
|
||||
err |= __put_user(&s->insn[0], &s->insnlist.insns);
|
||||
if (err) {
|
||||
if (err)
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
/* Copy insn structures. */
|
||||
for (n = 0; n < n_insns; n++) {
|
||||
rc = get_compat_insn(&s->insn[n], &insn32[n]);
|
||||
if (rc) {
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
return translated_ioctl(file, COMEDI_INSNLIST,
|
||||
|
@ -419,17 +410,16 @@ static int compat_insnlist(struct file *file, unsigned long arg)
|
|||
/* Handle 32-bit COMEDI_INSN ioctl. */
|
||||
static int compat_insn(struct file *file, unsigned long arg)
|
||||
{
|
||||
comedi_insn __user *insn;
|
||||
comedi32_insn __user *insn32;
|
||||
struct comedi_insn __user *insn;
|
||||
struct comedi32_insn_struct __user *insn32;
|
||||
int rc;
|
||||
|
||||
insn32 = compat_ptr(arg);
|
||||
insn = compat_alloc_user_space(sizeof(*insn));
|
||||
|
||||
rc = get_compat_insn(insn, insn32);
|
||||
if (rc) {
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
return translated_ioctl(file, COMEDI_INSN, (unsigned long)insn);
|
||||
}
|
||||
|
@ -512,14 +502,14 @@ static int mapped_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg,
|
|||
int rc;
|
||||
|
||||
/* Make sure we are dealing with a Comedi device. */
|
||||
if (imajor(file->f_dentry->d_inode) != COMEDI_MAJOR) {
|
||||
if (imajor(file->f_dentry->d_inode) != COMEDI_MAJOR)
|
||||
return -ENOTTY;
|
||||
}
|
||||
|
||||
rc = raw_ioctl(file, cmd, arg);
|
||||
/* Do not return -ENOIOCTLCMD. */
|
||||
if (rc == -ENOIOCTLCMD) {
|
||||
if (rc == -ENOIOCTLCMD)
|
||||
rc = -ENOTTY;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
@ -59,33 +59,39 @@ int comedi_debug;
|
|||
module_param(comedi_debug, int, 0644);
|
||||
#endif
|
||||
|
||||
int comedi_autoconfig = 1;
|
||||
module_param(comedi_autoconfig, bool, 0444);
|
||||
|
||||
int comedi_num_legacy_minors = 0;
|
||||
module_param(comedi_num_legacy_minors, int, 0444);
|
||||
|
||||
static DEFINE_SPINLOCK(comedi_file_info_table_lock);
|
||||
static struct comedi_device_file_info
|
||||
*comedi_file_info_table[COMEDI_NUM_MINORS];
|
||||
|
||||
static int do_devconfig_ioctl(comedi_device *dev, comedi_devconfig *arg);
|
||||
static int do_bufconfig_ioctl(comedi_device *dev, void *arg);
|
||||
static int do_devinfo_ioctl(comedi_device *dev, comedi_devinfo *arg,
|
||||
static int do_devconfig_ioctl(struct comedi_device *dev, struct comedi_devconfig *arg);
|
||||
static int do_bufconfig_ioctl(struct comedi_device *dev, void *arg);
|
||||
static int do_devinfo_ioctl(struct comedi_device *dev, struct comedi_devinfo *arg,
|
||||
struct file *file);
|
||||
static int do_subdinfo_ioctl(comedi_device *dev, comedi_subdinfo *arg,
|
||||
static int do_subdinfo_ioctl(struct comedi_device *dev, struct comedi_subdinfo *arg,
|
||||
void *file);
|
||||
static int do_chaninfo_ioctl(comedi_device *dev, comedi_chaninfo *arg);
|
||||
static int do_bufinfo_ioctl(comedi_device *dev, void *arg);
|
||||
static int do_cmd_ioctl(comedi_device *dev, void *arg, void *file);
|
||||
static int do_lock_ioctl(comedi_device *dev, unsigned int arg, void *file);
|
||||
static int do_unlock_ioctl(comedi_device *dev, unsigned int arg, void *file);
|
||||
static int do_cancel_ioctl(comedi_device *dev, unsigned int arg, void *file);
|
||||
static int do_cmdtest_ioctl(comedi_device *dev, void *arg, void *file);
|
||||
static int do_insnlist_ioctl(comedi_device *dev, void *arg, void *file);
|
||||
static int do_insn_ioctl(comedi_device *dev, void *arg, void *file);
|
||||
static int do_poll_ioctl(comedi_device *dev, unsigned int subd, void *file);
|
||||
static int do_chaninfo_ioctl(struct comedi_device *dev, struct comedi_chaninfo *arg);
|
||||
static int do_bufinfo_ioctl(struct comedi_device *dev, void *arg);
|
||||
static int do_cmd_ioctl(struct comedi_device *dev, void *arg, void *file);
|
||||
static int do_lock_ioctl(struct comedi_device *dev, unsigned int arg, void *file);
|
||||
static int do_unlock_ioctl(struct comedi_device *dev, unsigned int arg, void *file);
|
||||
static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg, void *file);
|
||||
static int do_cmdtest_ioctl(struct comedi_device *dev, void *arg, void *file);
|
||||
static int do_insnlist_ioctl(struct comedi_device *dev, void *arg, void *file);
|
||||
static int do_insn_ioctl(struct comedi_device *dev, void *arg, void *file);
|
||||
static int do_poll_ioctl(struct comedi_device *dev, unsigned int subd, void *file);
|
||||
|
||||
extern void do_become_nonbusy(comedi_device *dev, comedi_subdevice *s);
|
||||
static int do_cancel(comedi_device *dev, comedi_subdevice *s);
|
||||
extern void do_become_nonbusy(struct comedi_device *dev, struct comedi_subdevice *s);
|
||||
static int do_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
|
||||
|
||||
static int comedi_fasync(int fd, struct file *file, int on);
|
||||
|
||||
static int is_device_busy(comedi_device *dev);
|
||||
static int is_device_busy(struct comedi_device *dev);
|
||||
|
||||
#ifdef HAVE_UNLOCKED_IOCTL
|
||||
static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
|
||||
|
@ -98,9 +104,13 @@ static int comedi_ioctl(struct inode *inode, struct file *file,
|
|||
const unsigned minor = iminor(file->f_dentry->d_inode);
|
||||
struct comedi_device_file_info *dev_file_info =
|
||||
comedi_get_device_file_info(minor);
|
||||
comedi_device *dev = dev_file_info->device;
|
||||
struct comedi_device *dev;
|
||||
int rc;
|
||||
|
||||
if (dev_file_info == NULL || dev_file_info->device == NULL)
|
||||
return -ENODEV;
|
||||
dev = dev_file_info->device;
|
||||
|
||||
mutex_lock(&dev->mutex);
|
||||
|
||||
/* Device config is special, because it must work on
|
||||
|
@ -182,9 +192,9 @@ done:
|
|||
writes:
|
||||
none
|
||||
*/
|
||||
static int do_devconfig_ioctl(comedi_device *dev, comedi_devconfig *arg)
|
||||
static int do_devconfig_ioctl(struct comedi_device *dev, struct comedi_devconfig *arg)
|
||||
{
|
||||
comedi_devconfig it;
|
||||
struct comedi_devconfig it;
|
||||
int ret;
|
||||
unsigned char *aux_data = NULL;
|
||||
int aux_len;
|
||||
|
@ -203,7 +213,7 @@ static int do_devconfig_ioctl(comedi_device *dev, comedi_devconfig *arg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (copy_from_user(&it, arg, sizeof(comedi_devconfig)))
|
||||
if (copy_from_user(&it, arg, sizeof(struct comedi_devconfig)))
|
||||
return -EFAULT;
|
||||
|
||||
it.board_name[COMEDI_NAMELEN - 1] = 0;
|
||||
|
@ -262,14 +272,14 @@ static int do_devconfig_ioctl(comedi_device *dev, comedi_devconfig *arg)
|
|||
modified bufconfig at arg
|
||||
|
||||
*/
|
||||
static int do_bufconfig_ioctl(comedi_device *dev, void *arg)
|
||||
static int do_bufconfig_ioctl(struct comedi_device *dev, void *arg)
|
||||
{
|
||||
comedi_bufconfig bc;
|
||||
comedi_async *async;
|
||||
comedi_subdevice *s;
|
||||
struct comedi_bufconfig bc;
|
||||
struct comedi_async *async;
|
||||
struct comedi_subdevice *s;
|
||||
int ret = 0;
|
||||
|
||||
if (copy_from_user(&bc, arg, sizeof(comedi_bufconfig)))
|
||||
if (copy_from_user(&bc, arg, sizeof(struct comedi_bufconfig)))
|
||||
return -EFAULT;
|
||||
|
||||
if (bc.subdevice >= dev->n_subdevices || bc.subdevice < 0)
|
||||
|
@ -330,7 +340,7 @@ static int do_bufconfig_ioctl(comedi_device *dev, void *arg)
|
|||
bc.maximum_size = async->max_bufsize;
|
||||
|
||||
copyback:
|
||||
if (copy_to_user(arg, &bc, sizeof(comedi_bufconfig)))
|
||||
if (copy_to_user(arg, &bc, sizeof(struct comedi_bufconfig)))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
|
@ -350,16 +360,16 @@ copyback:
|
|||
devinfo structure
|
||||
|
||||
*/
|
||||
static int do_devinfo_ioctl(comedi_device *dev, comedi_devinfo *arg,
|
||||
static int do_devinfo_ioctl(struct comedi_device *dev, struct comedi_devinfo *arg,
|
||||
struct file *file)
|
||||
{
|
||||
comedi_devinfo devinfo;
|
||||
struct comedi_devinfo devinfo;
|
||||
const unsigned minor = iminor(file->f_dentry->d_inode);
|
||||
struct comedi_device_file_info *dev_file_info =
|
||||
comedi_get_device_file_info(minor);
|
||||
comedi_subdevice *read_subdev =
|
||||
struct comedi_subdevice *read_subdev =
|
||||
comedi_get_read_subdevice(dev_file_info);
|
||||
comedi_subdevice *write_subdev =
|
||||
struct comedi_subdevice *write_subdev =
|
||||
comedi_get_write_subdevice(dev_file_info);
|
||||
|
||||
memset(&devinfo, 0, sizeof(devinfo));
|
||||
|
@ -380,7 +390,7 @@ static int do_devinfo_ioctl(comedi_device *dev, comedi_devinfo *arg,
|
|||
else
|
||||
devinfo.write_subdevice = -1;
|
||||
|
||||
if (copy_to_user(arg, &devinfo, sizeof(comedi_devinfo)))
|
||||
if (copy_to_user(arg, &devinfo, sizeof(struct comedi_devinfo)))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
|
@ -400,14 +410,14 @@ static int do_devinfo_ioctl(comedi_device *dev, comedi_devinfo *arg,
|
|||
array of subdevice info structures at arg
|
||||
|
||||
*/
|
||||
static int do_subdinfo_ioctl(comedi_device *dev, comedi_subdinfo *arg,
|
||||
static int do_subdinfo_ioctl(struct comedi_device *dev, struct comedi_subdinfo *arg,
|
||||
void *file)
|
||||
{
|
||||
int ret, i;
|
||||
comedi_subdinfo *tmp, *us;
|
||||
comedi_subdevice *s;
|
||||
struct comedi_subdinfo *tmp, *us;
|
||||
struct comedi_subdevice *s;
|
||||
|
||||
tmp = kcalloc(dev->n_subdevices, sizeof(comedi_subdinfo), GFP_KERNEL);
|
||||
tmp = kcalloc(dev->n_subdevices, sizeof(struct comedi_subdinfo), GFP_KERNEL);
|
||||
if (!tmp)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -459,7 +469,7 @@ static int do_subdinfo_ioctl(comedi_device *dev, comedi_subdinfo *arg,
|
|||
}
|
||||
|
||||
ret = copy_to_user(arg, tmp,
|
||||
dev->n_subdevices * sizeof(comedi_subdinfo));
|
||||
dev->n_subdevices * sizeof(struct comedi_subdinfo));
|
||||
|
||||
kfree(tmp);
|
||||
|
||||
|
@ -480,12 +490,12 @@ static int do_subdinfo_ioctl(comedi_device *dev, comedi_subdinfo *arg,
|
|||
arrays at elements of chaninfo structure
|
||||
|
||||
*/
|
||||
static int do_chaninfo_ioctl(comedi_device *dev, comedi_chaninfo *arg)
|
||||
static int do_chaninfo_ioctl(struct comedi_device *dev, struct comedi_chaninfo *arg)
|
||||
{
|
||||
comedi_subdevice *s;
|
||||
comedi_chaninfo it;
|
||||
struct comedi_subdevice *s;
|
||||
struct comedi_chaninfo it;
|
||||
|
||||
if (copy_from_user(&it, arg, sizeof(comedi_chaninfo)))
|
||||
if (copy_from_user(&it, arg, sizeof(struct comedi_chaninfo)))
|
||||
return -EFAULT;
|
||||
|
||||
if (it.subdev >= dev->n_subdevices)
|
||||
|
@ -496,7 +506,7 @@ static int do_chaninfo_ioctl(comedi_device *dev, comedi_chaninfo *arg)
|
|||
if (s->maxdata || !s->maxdata_list)
|
||||
return -EINVAL;
|
||||
if (copy_to_user(it.maxdata_list, s->maxdata_list,
|
||||
s->n_chan * sizeof(lsampl_t)))
|
||||
s->n_chan * sizeof(unsigned int)))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
|
@ -544,13 +554,13 @@ static int do_chaninfo_ioctl(comedi_device *dev, comedi_chaninfo *arg)
|
|||
modified bufinfo at arg
|
||||
|
||||
*/
|
||||
static int do_bufinfo_ioctl(comedi_device *dev, void *arg)
|
||||
static int do_bufinfo_ioctl(struct comedi_device *dev, void *arg)
|
||||
{
|
||||
comedi_bufinfo bi;
|
||||
comedi_subdevice *s;
|
||||
comedi_async *async;
|
||||
struct comedi_bufinfo bi;
|
||||
struct comedi_subdevice *s;
|
||||
struct comedi_async *async;
|
||||
|
||||
if (copy_from_user(&bi, arg, sizeof(comedi_bufinfo)))
|
||||
if (copy_from_user(&bi, arg, sizeof(struct comedi_bufinfo)))
|
||||
return -EFAULT;
|
||||
|
||||
if (bi.subdevice >= dev->n_subdevices || bi.subdevice < 0)
|
||||
|
@ -591,13 +601,13 @@ static int do_bufinfo_ioctl(comedi_device *dev, void *arg)
|
|||
bi.buf_read_ptr = async->buf_read_ptr;
|
||||
|
||||
copyback:
|
||||
if (copy_to_user(arg, &bi, sizeof(comedi_bufinfo)))
|
||||
if (copy_to_user(arg, &bi, sizeof(struct comedi_bufinfo)))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_insn(comedi_device *dev, comedi_insn *insn, lsampl_t *data,
|
||||
static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data,
|
||||
void *file);
|
||||
/*
|
||||
* COMEDI_INSNLIST
|
||||
|
@ -616,25 +626,25 @@ static int parse_insn(comedi_device *dev, comedi_insn *insn, lsampl_t *data,
|
|||
*/
|
||||
/* arbitrary limits */
|
||||
#define MAX_SAMPLES 256
|
||||
static int do_insnlist_ioctl(comedi_device *dev, void *arg, void *file)
|
||||
static int do_insnlist_ioctl(struct comedi_device *dev, void *arg, void *file)
|
||||
{
|
||||
comedi_insnlist insnlist;
|
||||
comedi_insn *insns = NULL;
|
||||
lsampl_t *data = NULL;
|
||||
struct comedi_insnlist insnlist;
|
||||
struct comedi_insn *insns = NULL;
|
||||
unsigned int *data = NULL;
|
||||
int i = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (copy_from_user(&insnlist, arg, sizeof(comedi_insnlist)))
|
||||
if (copy_from_user(&insnlist, arg, sizeof(struct comedi_insnlist)))
|
||||
return -EFAULT;
|
||||
|
||||
data = kmalloc(sizeof(lsampl_t) * MAX_SAMPLES, GFP_KERNEL);
|
||||
data = kmalloc(sizeof(unsigned int) * MAX_SAMPLES, GFP_KERNEL);
|
||||
if (!data) {
|
||||
DPRINTK("kmalloc failed\n");
|
||||
ret = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
insns = kmalloc(sizeof(comedi_insn) * insnlist.n_insns, GFP_KERNEL);
|
||||
insns = kmalloc(sizeof(struct comedi_insn) * insnlist.n_insns, GFP_KERNEL);
|
||||
if (!insns) {
|
||||
DPRINTK("kmalloc failed\n");
|
||||
ret = -ENOMEM;
|
||||
|
@ -642,7 +652,7 @@ static int do_insnlist_ioctl(comedi_device *dev, void *arg, void *file)
|
|||
}
|
||||
|
||||
if (copy_from_user(insns, insnlist.insns,
|
||||
sizeof(comedi_insn) * insnlist.n_insns)) {
|
||||
sizeof(struct comedi_insn) * insnlist.n_insns)) {
|
||||
DPRINTK("copy_from_user failed\n");
|
||||
ret = -EFAULT;
|
||||
goto error;
|
||||
|
@ -656,7 +666,7 @@ static int do_insnlist_ioctl(comedi_device *dev, void *arg, void *file)
|
|||
}
|
||||
if (insns[i].insn & INSN_MASK_WRITE) {
|
||||
if (copy_from_user(data, insns[i].data,
|
||||
insns[i].n * sizeof(lsampl_t))) {
|
||||
insns[i].n * sizeof(unsigned int))) {
|
||||
DPRINTK("copy_from_user failed\n");
|
||||
ret = -EFAULT;
|
||||
goto error;
|
||||
|
@ -667,7 +677,7 @@ static int do_insnlist_ioctl(comedi_device *dev, void *arg, void *file)
|
|||
goto error;
|
||||
if (insns[i].insn & INSN_MASK_READ) {
|
||||
if (copy_to_user(insns[i].data, data,
|
||||
insns[i].n * sizeof(lsampl_t))) {
|
||||
insns[i].n * sizeof(unsigned int))) {
|
||||
DPRINTK("copy_to_user failed\n");
|
||||
ret = -EFAULT;
|
||||
goto error;
|
||||
|
@ -686,7 +696,7 @@ error:
|
|||
return i;
|
||||
}
|
||||
|
||||
static int check_insn_config_length(comedi_insn *insn, lsampl_t *data)
|
||||
static int check_insn_config_length(struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
if (insn->n < 1)
|
||||
return -EINVAL;
|
||||
|
@ -747,10 +757,10 @@ static int check_insn_config_length(comedi_insn *insn, lsampl_t *data)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int parse_insn(comedi_device *dev, comedi_insn *insn, lsampl_t *data,
|
||||
static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data,
|
||||
void *file)
|
||||
{
|
||||
comedi_subdevice *s;
|
||||
struct comedi_subdevice *s;
|
||||
int ret = 0;
|
||||
int i;
|
||||
|
||||
|
@ -815,7 +825,7 @@ static int parse_insn(comedi_device *dev, comedi_insn *insn, lsampl_t *data,
|
|||
}
|
||||
} else {
|
||||
/* a subdevice instruction */
|
||||
lsampl_t maxdata;
|
||||
unsigned int maxdata;
|
||||
|
||||
if (insn->subdev >= dev->n_subdevices) {
|
||||
DPRINTK("subdevice %d out of range\n", insn->subdev);
|
||||
|
@ -901,25 +911,25 @@ out:
|
|||
* pointer to insn
|
||||
*
|
||||
* reads:
|
||||
* comedi_insn struct at arg
|
||||
* struct comedi_insn struct at arg
|
||||
* data (for writes)
|
||||
*
|
||||
* writes:
|
||||
* data (for reads)
|
||||
*/
|
||||
static int do_insn_ioctl(comedi_device *dev, void *arg, void *file)
|
||||
static int do_insn_ioctl(struct comedi_device *dev, void *arg, void *file)
|
||||
{
|
||||
comedi_insn insn;
|
||||
lsampl_t *data = NULL;
|
||||
struct comedi_insn insn;
|
||||
unsigned int *data = NULL;
|
||||
int ret = 0;
|
||||
|
||||
data = kmalloc(sizeof(lsampl_t) * MAX_SAMPLES, GFP_KERNEL);
|
||||
data = kmalloc(sizeof(unsigned int) * MAX_SAMPLES, GFP_KERNEL);
|
||||
if (!data) {
|
||||
ret = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (copy_from_user(&insn, arg, sizeof(comedi_insn))) {
|
||||
if (copy_from_user(&insn, arg, sizeof(struct comedi_insn))) {
|
||||
ret = -EFAULT;
|
||||
goto error;
|
||||
}
|
||||
|
@ -928,7 +938,7 @@ static int do_insn_ioctl(comedi_device *dev, void *arg, void *file)
|
|||
if (insn.n > MAX_SAMPLES)
|
||||
insn.n = MAX_SAMPLES;
|
||||
if (insn.insn & INSN_MASK_WRITE) {
|
||||
if (copy_from_user(data, insn.data, insn.n * sizeof(lsampl_t))) {
|
||||
if (copy_from_user(data, insn.data, insn.n * sizeof(unsigned int))) {
|
||||
ret = -EFAULT;
|
||||
goto error;
|
||||
}
|
||||
|
@ -937,7 +947,7 @@ static int do_insn_ioctl(comedi_device *dev, void *arg, void *file)
|
|||
if (ret < 0)
|
||||
goto error;
|
||||
if (insn.insn & INSN_MASK_READ) {
|
||||
if (copy_to_user(insn.data, data, insn.n * sizeof(lsampl_t))) {
|
||||
if (copy_to_user(insn.data, data, insn.n * sizeof(unsigned int))) {
|
||||
ret = -EFAULT;
|
||||
goto error;
|
||||
}
|
||||
|
@ -965,15 +975,15 @@ error:
|
|||
modified cmd structure at arg
|
||||
|
||||
*/
|
||||
static int do_cmd_ioctl(comedi_device *dev, void *arg, void *file)
|
||||
static int do_cmd_ioctl(struct comedi_device *dev, void *arg, void *file)
|
||||
{
|
||||
comedi_cmd user_cmd;
|
||||
comedi_subdevice *s;
|
||||
comedi_async *async;
|
||||
struct comedi_cmd user_cmd;
|
||||
struct comedi_subdevice *s;
|
||||
struct comedi_async *async;
|
||||
int ret = 0;
|
||||
unsigned int *chanlist_saver = NULL;
|
||||
|
||||
if (copy_from_user(&user_cmd, arg, sizeof(comedi_cmd))) {
|
||||
if (copy_from_user(&user_cmd, arg, sizeof(struct comedi_cmd))) {
|
||||
DPRINTK("bad cmd address\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
@ -1062,7 +1072,7 @@ static int do_cmd_ioctl(comedi_device *dev, void *arg, void *file)
|
|||
/* restore chanlist pointer before copying back */
|
||||
user_cmd.chanlist = chanlist_saver;
|
||||
user_cmd.data = NULL;
|
||||
if (copy_to_user(arg, &user_cmd, sizeof(comedi_cmd))) {
|
||||
if (copy_to_user(arg, &user_cmd, sizeof(struct comedi_cmd))) {
|
||||
DPRINTK("fault writing cmd\n");
|
||||
ret = -EFAULT;
|
||||
goto cleanup;
|
||||
|
@ -1119,15 +1129,15 @@ cleanup:
|
|||
modified cmd structure at arg
|
||||
|
||||
*/
|
||||
static int do_cmdtest_ioctl(comedi_device *dev, void *arg, void *file)
|
||||
static int do_cmdtest_ioctl(struct comedi_device *dev, void *arg, void *file)
|
||||
{
|
||||
comedi_cmd user_cmd;
|
||||
comedi_subdevice *s;
|
||||
struct comedi_cmd user_cmd;
|
||||
struct comedi_subdevice *s;
|
||||
int ret = 0;
|
||||
unsigned int *chanlist = NULL;
|
||||
unsigned int *chanlist_saver = NULL;
|
||||
|
||||
if (copy_from_user(&user_cmd, arg, sizeof(comedi_cmd))) {
|
||||
if (copy_from_user(&user_cmd, arg, sizeof(struct comedi_cmd))) {
|
||||
DPRINTK("bad cmd address\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
@ -1191,7 +1201,7 @@ static int do_cmdtest_ioctl(comedi_device *dev, void *arg, void *file)
|
|||
/* restore chanlist pointer before copying back */
|
||||
user_cmd.chanlist = chanlist_saver;
|
||||
|
||||
if (copy_to_user(arg, &user_cmd, sizeof(comedi_cmd))) {
|
||||
if (copy_to_user(arg, &user_cmd, sizeof(struct comedi_cmd))) {
|
||||
DPRINTK("bad cmd address\n");
|
||||
ret = -EFAULT;
|
||||
goto cleanup;
|
||||
|
@ -1217,11 +1227,11 @@ cleanup:
|
|||
|
||||
*/
|
||||
|
||||
static int do_lock_ioctl(comedi_device *dev, unsigned int arg, void *file)
|
||||
static int do_lock_ioctl(struct comedi_device *dev, unsigned int arg, void *file)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned long flags;
|
||||
comedi_subdevice *s;
|
||||
struct comedi_subdevice *s;
|
||||
|
||||
if (arg >= dev->n_subdevices)
|
||||
return -EINVAL;
|
||||
|
@ -1261,9 +1271,9 @@ static int do_lock_ioctl(comedi_device *dev, unsigned int arg, void *file)
|
|||
This function isn't protected by the semaphore, since
|
||||
we already own the lock.
|
||||
*/
|
||||
static int do_unlock_ioctl(comedi_device *dev, unsigned int arg, void *file)
|
||||
static int do_unlock_ioctl(struct comedi_device *dev, unsigned int arg, void *file)
|
||||
{
|
||||
comedi_subdevice *s;
|
||||
struct comedi_subdevice *s;
|
||||
|
||||
if (arg >= dev->n_subdevices)
|
||||
return -EINVAL;
|
||||
|
@ -1301,9 +1311,9 @@ static int do_unlock_ioctl(comedi_device *dev, unsigned int arg, void *file)
|
|||
nothing
|
||||
|
||||
*/
|
||||
static int do_cancel_ioctl(comedi_device *dev, unsigned int arg, void *file)
|
||||
static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg, void *file)
|
||||
{
|
||||
comedi_subdevice *s;
|
||||
struct comedi_subdevice *s;
|
||||
|
||||
if (arg >= dev->n_subdevices)
|
||||
return -EINVAL;
|
||||
|
@ -1337,9 +1347,9 @@ static int do_cancel_ioctl(comedi_device *dev, unsigned int arg, void *file)
|
|||
nothing
|
||||
|
||||
*/
|
||||
static int do_poll_ioctl(comedi_device *dev, unsigned int arg, void *file)
|
||||
static int do_poll_ioctl(struct comedi_device *dev, unsigned int arg, void *file)
|
||||
{
|
||||
comedi_subdevice *s;
|
||||
struct comedi_subdevice *s;
|
||||
|
||||
if (arg >= dev->n_subdevices)
|
||||
return -EINVAL;
|
||||
|
@ -1360,7 +1370,7 @@ static int do_poll_ioctl(comedi_device *dev, unsigned int arg, void *file)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int do_cancel(comedi_device *dev, comedi_subdevice *s)
|
||||
static int do_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
|
@ -1374,8 +1384,8 @@ static int do_cancel(comedi_device *dev, comedi_subdevice *s)
|
|||
|
||||
void comedi_unmap(struct vm_area_struct *area)
|
||||
{
|
||||
comedi_async *async;
|
||||
comedi_device *dev;
|
||||
struct comedi_async *async;
|
||||
struct comedi_device *dev;
|
||||
|
||||
async = area->vm_private_data;
|
||||
dev = async->subdevice->device;
|
||||
|
@ -1394,14 +1404,14 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
|
|||
const unsigned minor = iminor(file->f_dentry->d_inode);
|
||||
struct comedi_device_file_info *dev_file_info =
|
||||
comedi_get_device_file_info(minor);
|
||||
comedi_device *dev = dev_file_info->device;
|
||||
comedi_async *async = NULL;
|
||||
struct comedi_device *dev = dev_file_info->device;
|
||||
struct comedi_async *async = NULL;
|
||||
unsigned long start = vma->vm_start;
|
||||
unsigned long size;
|
||||
int n_pages;
|
||||
int i;
|
||||
int retval;
|
||||
comedi_subdevice *s;
|
||||
struct comedi_subdevice *s;
|
||||
|
||||
mutex_lock(&dev->mutex);
|
||||
if (!dev->attached) {
|
||||
|
@ -1470,9 +1480,9 @@ static unsigned int comedi_poll(struct file *file, poll_table *wait)
|
|||
const unsigned minor = iminor(file->f_dentry->d_inode);
|
||||
struct comedi_device_file_info *dev_file_info =
|
||||
comedi_get_device_file_info(minor);
|
||||
comedi_device *dev = dev_file_info->device;
|
||||
comedi_subdevice *read_subdev;
|
||||
comedi_subdevice *write_subdev;
|
||||
struct comedi_device *dev = dev_file_info->device;
|
||||
struct comedi_subdevice *read_subdev;
|
||||
struct comedi_subdevice *write_subdev;
|
||||
|
||||
mutex_lock(&dev->mutex);
|
||||
if (!dev->attached) {
|
||||
|
@ -1513,14 +1523,14 @@ static unsigned int comedi_poll(struct file *file, poll_table *wait)
|
|||
static ssize_t comedi_write(struct file *file, const char *buf, size_t nbytes,
|
||||
loff_t *offset)
|
||||
{
|
||||
comedi_subdevice *s;
|
||||
comedi_async *async;
|
||||
struct comedi_subdevice *s;
|
||||
struct comedi_async *async;
|
||||
int n, m, count = 0, retval = 0;
|
||||
DECLARE_WAITQUEUE(wait, current);
|
||||
const unsigned minor = iminor(file->f_dentry->d_inode);
|
||||
struct comedi_device_file_info *dev_file_info =
|
||||
comedi_get_device_file_info(minor);
|
||||
comedi_device *dev = dev_file_info->device;
|
||||
struct comedi_device *dev = dev_file_info->device;
|
||||
|
||||
if (!dev->attached) {
|
||||
DPRINTK("no driver configured on comedi%i\n", dev->minor);
|
||||
|
@ -1615,14 +1625,14 @@ done:
|
|||
static ssize_t comedi_read(struct file *file, char *buf, size_t nbytes,
|
||||
loff_t *offset)
|
||||
{
|
||||
comedi_subdevice *s;
|
||||
comedi_async *async;
|
||||
struct comedi_subdevice *s;
|
||||
struct comedi_async *async;
|
||||
int n, m, count = 0, retval = 0;
|
||||
DECLARE_WAITQUEUE(wait, current);
|
||||
const unsigned minor = iminor(file->f_dentry->d_inode);
|
||||
struct comedi_device_file_info *dev_file_info =
|
||||
comedi_get_device_file_info(minor);
|
||||
comedi_device *dev = dev_file_info->device;
|
||||
struct comedi_device *dev = dev_file_info->device;
|
||||
|
||||
if (!dev->attached) {
|
||||
DPRINTK("no driver configured on comedi%i\n", dev->minor);
|
||||
|
@ -1723,9 +1733,9 @@ done:
|
|||
/*
|
||||
This function restores a subdevice to an idle state.
|
||||
*/
|
||||
void do_become_nonbusy(comedi_device *dev, comedi_subdevice *s)
|
||||
void do_become_nonbusy(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
{
|
||||
comedi_async *async = s->async;
|
||||
struct comedi_async *async = s->async;
|
||||
|
||||
comedi_set_subdevice_runflags(s, SRF_RUNNING, 0);
|
||||
#ifdef CONFIG_COMEDI_RT
|
||||
|
@ -1747,11 +1757,11 @@ void do_become_nonbusy(comedi_device *dev, comedi_subdevice *s)
|
|||
|
||||
static int comedi_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
char mod[32];
|
||||
const unsigned minor = iminor(inode);
|
||||
struct comedi_device_file_info *dev_file_info =
|
||||
comedi_get_device_file_info(minor);
|
||||
comedi_device *dev = dev_file_info->device;
|
||||
struct comedi_device *dev = dev_file_info ? dev_file_info->device : NULL;
|
||||
|
||||
if (dev == NULL) {
|
||||
DPRINTK("invalid minor number\n");
|
||||
return -ENODEV;
|
||||
|
@ -1783,10 +1793,9 @@ static int comedi_open(struct inode *inode, struct file *file)
|
|||
|
||||
dev->in_request_module = 1;
|
||||
|
||||
sprintf(mod, "char-major-%i-%i", COMEDI_MAJOR, dev->minor);
|
||||
#ifdef CONFIG_KMOD
|
||||
mutex_unlock(&dev->mutex);
|
||||
request_module(mod);
|
||||
request_module("char-major-%i-%i", COMEDI_MAJOR, dev->minor);
|
||||
mutex_lock(&dev->mutex);
|
||||
#endif
|
||||
|
||||
|
@ -1823,8 +1832,8 @@ static int comedi_close(struct inode *inode, struct file *file)
|
|||
const unsigned minor = iminor(inode);
|
||||
struct comedi_device_file_info *dev_file_info =
|
||||
comedi_get_device_file_info(minor);
|
||||
comedi_device *dev = dev_file_info->device;
|
||||
comedi_subdevice *s = NULL;
|
||||
struct comedi_device *dev = dev_file_info->device;
|
||||
struct comedi_subdevice *s = NULL;
|
||||
int i;
|
||||
|
||||
mutex_lock(&dev->mutex);
|
||||
|
@ -1862,7 +1871,7 @@ static int comedi_fasync(int fd, struct file *file, int on)
|
|||
struct comedi_device_file_info *dev_file_info =
|
||||
comedi_get_device_file_info(minor);
|
||||
|
||||
comedi_device *dev = dev_file_info->device;
|
||||
struct comedi_device *dev = dev_file_info->device;
|
||||
|
||||
return fasync_helper(fd, file, on, &dev->async_queue);
|
||||
}
|
||||
|
@ -1893,7 +1902,7 @@ static void comedi_cleanup_legacy_minors(void)
|
|||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < COMEDI_NUM_LEGACY_MINORS; i++)
|
||||
for (i = 0; i < comedi_num_legacy_minors; i++)
|
||||
comedi_free_board_minor(i);
|
||||
}
|
||||
|
||||
|
@ -1905,6 +1914,22 @@ static int __init comedi_init(void)
|
|||
printk(KERN_INFO "comedi: version " COMEDI_RELEASE
|
||||
" - http://www.comedi.org\n");
|
||||
|
||||
if (comedi_num_legacy_minors < 0 ||
|
||||
comedi_num_legacy_minors > COMEDI_NUM_BOARD_MINORS) {
|
||||
printk(KERN_ERR "comedi: error: invalid value for module "
|
||||
"parameter \"comedi_num_legacy_minors\". Valid values "
|
||||
"are 0 through %i.\n", COMEDI_NUM_BOARD_MINORS);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* comedi is unusable if both comedi_autoconfig and
|
||||
* comedi_num_legacy_minors are zero, so we might as well adjust the
|
||||
* defaults in that case
|
||||
*/
|
||||
if (comedi_autoconfig == 0 && comedi_num_legacy_minors == 0)
|
||||
comedi_num_legacy_minors = 16;
|
||||
|
||||
memset(comedi_file_info_table, 0,
|
||||
sizeof(struct comedi_device_file_info *) * COMEDI_NUM_MINORS);
|
||||
|
||||
|
@ -1933,7 +1958,7 @@ static int __init comedi_init(void)
|
|||
comedi_proc_init();
|
||||
|
||||
/* create devices files for legacy/manual use */
|
||||
for (i = 0; i < COMEDI_NUM_LEGACY_MINORS; i++) {
|
||||
for (i = 0; i < comedi_num_legacy_minors; i++) {
|
||||
int minor;
|
||||
minor = comedi_alloc_board_minor(NULL);
|
||||
if (minor < 0) {
|
||||
|
@ -1975,15 +2000,15 @@ static void __exit comedi_cleanup(void)
|
|||
module_init(comedi_init);
|
||||
module_exit(comedi_cleanup);
|
||||
|
||||
void comedi_error(const comedi_device *dev, const char *s)
|
||||
void comedi_error(const struct comedi_device *dev, const char *s)
|
||||
{
|
||||
rt_printk("comedi%d: %s: %s\n", dev->minor, dev->driver->driver_name,
|
||||
s);
|
||||
}
|
||||
|
||||
void comedi_event(comedi_device *dev, comedi_subdevice *s)
|
||||
void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
{
|
||||
comedi_async *async = s->async;
|
||||
struct comedi_async *async = s->async;
|
||||
unsigned runflags = 0;
|
||||
unsigned runflags_mask = 0;
|
||||
|
||||
|
@ -2042,7 +2067,7 @@ void comedi_event(comedi_device *dev, comedi_subdevice *s)
|
|||
s->async->events = 0;
|
||||
}
|
||||
|
||||
void comedi_set_subdevice_runflags(comedi_subdevice *s, unsigned mask,
|
||||
void comedi_set_subdevice_runflags(struct comedi_subdevice *s, unsigned mask,
|
||||
unsigned bits)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
@ -2053,7 +2078,7 @@ void comedi_set_subdevice_runflags(comedi_subdevice *s, unsigned mask,
|
|||
comedi_spin_unlock_irqrestore(&s->spin_lock, flags);
|
||||
}
|
||||
|
||||
unsigned comedi_get_subdevice_runflags(comedi_subdevice *s)
|
||||
unsigned comedi_get_subdevice_runflags(struct comedi_subdevice *s)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned runflags;
|
||||
|
@ -2064,9 +2089,9 @@ unsigned comedi_get_subdevice_runflags(comedi_subdevice *s)
|
|||
return runflags;
|
||||
}
|
||||
|
||||
static int is_device_busy(comedi_device *dev)
|
||||
static int is_device_busy(struct comedi_device *dev)
|
||||
{
|
||||
comedi_subdevice *s;
|
||||
struct comedi_subdevice *s;
|
||||
int i;
|
||||
|
||||
if (!dev->attached)
|
||||
|
@ -2083,15 +2108,15 @@ static int is_device_busy(comedi_device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void comedi_device_init(comedi_device *dev)
|
||||
void comedi_device_init(struct comedi_device *dev)
|
||||
{
|
||||
memset(dev, 0, sizeof(comedi_device));
|
||||
memset(dev, 0, sizeof(struct comedi_device));
|
||||
spin_lock_init(&dev->spinlock);
|
||||
mutex_init(&dev->mutex);
|
||||
dev->minor = -1;
|
||||
}
|
||||
|
||||
void comedi_device_cleanup(comedi_device *dev)
|
||||
void comedi_device_cleanup(struct comedi_device *dev)
|
||||
{
|
||||
if (dev == NULL)
|
||||
return;
|
||||
|
@ -2105,13 +2130,13 @@ int comedi_alloc_board_minor(struct device *hardware_device)
|
|||
{
|
||||
unsigned long flags;
|
||||
struct comedi_device_file_info *info;
|
||||
device_create_result_type *csdev;
|
||||
struct device *csdev;
|
||||
unsigned i;
|
||||
|
||||
info = kzalloc(sizeof(struct comedi_device_file_info), GFP_KERNEL);
|
||||
if (info == NULL)
|
||||
return -ENOMEM;
|
||||
info->device = kzalloc(sizeof(comedi_device), GFP_KERNEL);
|
||||
info->device = kzalloc(sizeof(struct comedi_device), GFP_KERNEL);
|
||||
if (info->device == NULL) {
|
||||
kfree(info);
|
||||
return -ENOMEM;
|
||||
|
@ -2155,7 +2180,7 @@ void comedi_free_board_minor(unsigned minor)
|
|||
comedi_spin_unlock_irqrestore(&comedi_file_info_table_lock, flags);
|
||||
|
||||
if (info) {
|
||||
comedi_device *dev = info->device;
|
||||
struct comedi_device *dev = info->device;
|
||||
if (dev) {
|
||||
if (dev->class_dev) {
|
||||
device_destroy(comedi_class,
|
||||
|
@ -2168,11 +2193,11 @@ void comedi_free_board_minor(unsigned minor)
|
|||
}
|
||||
}
|
||||
|
||||
int comedi_alloc_subdevice_minor(comedi_device *dev, comedi_subdevice *s)
|
||||
int comedi_alloc_subdevice_minor(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct comedi_device_file_info *info;
|
||||
device_create_result_type *csdev;
|
||||
struct device *csdev;
|
||||
unsigned i;
|
||||
|
||||
info = kmalloc(sizeof(struct comedi_device_file_info), GFP_KERNEL);
|
||||
|
@ -2182,7 +2207,7 @@ int comedi_alloc_subdevice_minor(comedi_device *dev, comedi_subdevice *s)
|
|||
info->read_subdevice = s;
|
||||
info->write_subdevice = s;
|
||||
comedi_spin_lock_irqsave(&comedi_file_info_table_lock, flags);
|
||||
for (i = COMEDI_FIRST_SUBDEVICE_MINOR; i < COMEDI_NUM_BOARD_MINORS; ++i) {
|
||||
for (i = COMEDI_FIRST_SUBDEVICE_MINOR; i < COMEDI_NUM_MINORS; ++i) {
|
||||
if (comedi_file_info_table[i] == NULL) {
|
||||
comedi_file_info_table[i] = info;
|
||||
break;
|
||||
|
@ -2206,7 +2231,7 @@ int comedi_alloc_subdevice_minor(comedi_device *dev, comedi_subdevice *s)
|
|||
return i;
|
||||
}
|
||||
|
||||
void comedi_free_subdevice_minor(comedi_subdevice *s)
|
||||
void comedi_free_subdevice_minor(struct comedi_subdevice *s)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct comedi_device_file_info *info;
|
||||
|
|
|
@ -4,5 +4,6 @@
|
|||
|
||||
extern struct class *comedi_class;
|
||||
extern const struct file_operations comedi_fops;
|
||||
extern int comedi_autoconfig;
|
||||
|
||||
#endif /* _COMEDI_FOPS_H */
|
||||
|
|
|
@ -31,12 +31,12 @@
|
|||
/* for drivers */
|
||||
EXPORT_SYMBOL(comedi_driver_register);
|
||||
EXPORT_SYMBOL(comedi_driver_unregister);
|
||||
//EXPORT_SYMBOL(comedi_bufcheck);
|
||||
//EXPORT_SYMBOL(comedi_done);
|
||||
//EXPORT_SYMBOL(comedi_error_done);
|
||||
/* EXPORT_SYMBOL(comedi_bufcheck); */
|
||||
/* EXPORT_SYMBOL(comedi_done); */
|
||||
/* EXPORT_SYMBOL(comedi_error_done); */
|
||||
EXPORT_SYMBOL(comedi_error);
|
||||
//EXPORT_SYMBOL(comedi_eobuf);
|
||||
//EXPORT_SYMBOL(comedi_eos);
|
||||
/* EXPORT_SYMBOL(comedi_eobuf); */
|
||||
/* EXPORT_SYMBOL(comedi_eos); */
|
||||
EXPORT_SYMBOL(comedi_event);
|
||||
EXPORT_SYMBOL(comedi_get_subdevice_runflags);
|
||||
EXPORT_SYMBOL(comedi_set_subdevice_runflags);
|
||||
|
@ -60,6 +60,8 @@ EXPORT_SYMBOL_GPL(comedi_alloc_board_minor);
|
|||
EXPORT_SYMBOL_GPL(comedi_free_board_minor);
|
||||
EXPORT_SYMBOL_GPL(comedi_pci_auto_config);
|
||||
EXPORT_SYMBOL_GPL(comedi_pci_auto_unconfig);
|
||||
EXPORT_SYMBOL_GPL(comedi_usb_auto_config);
|
||||
EXPORT_SYMBOL_GPL(comedi_usb_auto_unconfig);
|
||||
|
||||
/* for kcomedilib */
|
||||
EXPORT_SYMBOL(check_chanlist);
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#error comedi_rt.h should only be included by comedidev.h
|
||||
#endif
|
||||
|
||||
#include <linux/version.h>
|
||||
#include <linux/kdev_t.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/errno.h>
|
||||
|
@ -59,12 +58,12 @@
|
|||
|
||||
int comedi_request_irq(unsigned int irq, irqreturn_t(*handler) (int,
|
||||
void *PT_REGS_ARG), unsigned long flags, const char *device,
|
||||
comedi_device *dev_id);
|
||||
void comedi_free_irq(unsigned int irq, comedi_device *dev_id);
|
||||
struct comedi_device *dev_id);
|
||||
void comedi_free_irq(unsigned int irq, struct comedi_device *dev_id);
|
||||
void comedi_rt_init(void);
|
||||
void comedi_rt_cleanup(void);
|
||||
int comedi_switch_to_rt(comedi_device *dev);
|
||||
void comedi_switch_to_non_rt(comedi_device *dev);
|
||||
int comedi_switch_to_rt(struct comedi_device *dev);
|
||||
void comedi_switch_to_non_rt(struct comedi_device *dev);
|
||||
void comedi_rt_pend_wakeup(wait_queue_head_t *q);
|
||||
extern int rt_pend_call(void (*func) (int arg1, void *arg2), int arg1,
|
||||
void *arg2);
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/kdev_t.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/errno.h>
|
||||
|
@ -36,7 +35,6 @@
|
|||
#include <linux/mm.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/mm.h>
|
||||
#include "interrupt.h"
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
@ -55,9 +53,9 @@
|
|||
|
||||
#define COMEDI_INITCLEANUP_NOMODULE(x) \
|
||||
static int __init x ## _init_module(void) \
|
||||
{return comedi_driver_register(&(x));} \
|
||||
{return comedi_driver_register(&(x)); } \
|
||||
static void __exit x ## _cleanup_module(void) \
|
||||
{comedi_driver_unregister(&(x));} \
|
||||
{comedi_driver_unregister(&(x)); } \
|
||||
module_init(x ## _init_module); \
|
||||
module_exit(x ## _cleanup_module); \
|
||||
|
||||
|
@ -120,23 +118,14 @@
|
|||
#define PCI_VENDOR_ID_MEILHAUS 0x1402
|
||||
|
||||
#define COMEDI_NUM_MINORS 0x100
|
||||
#define COMEDI_NUM_LEGACY_MINORS 0x10
|
||||
#define COMEDI_NUM_BOARD_MINORS 0x30
|
||||
#define COMEDI_FIRST_SUBDEVICE_MINOR COMEDI_NUM_BOARD_MINORS
|
||||
|
||||
typedef struct comedi_device_struct comedi_device;
|
||||
typedef struct comedi_subdevice_struct comedi_subdevice;
|
||||
typedef struct comedi_async_struct comedi_async;
|
||||
typedef struct comedi_driver_struct comedi_driver;
|
||||
typedef struct comedi_lrange_struct comedi_lrange;
|
||||
|
||||
typedef struct device device_create_result_type;
|
||||
|
||||
#define COMEDI_DEVICE_CREATE(cs, parent, devt, drvdata, device, fmt...) \
|
||||
device_create(cs, ((parent) ? (parent) : (device)), devt, drvdata, fmt)
|
||||
|
||||
struct comedi_subdevice_struct {
|
||||
comedi_device *device;
|
||||
struct comedi_subdevice {
|
||||
struct comedi_device *device;
|
||||
int type;
|
||||
int n_chan;
|
||||
volatile int subdev_flags;
|
||||
|
@ -144,7 +133,7 @@ struct comedi_subdevice_struct {
|
|||
|
||||
void *private;
|
||||
|
||||
comedi_async *async;
|
||||
struct comedi_async *async;
|
||||
|
||||
void *lock;
|
||||
void *busy;
|
||||
|
@ -153,46 +142,46 @@ struct comedi_subdevice_struct {
|
|||
|
||||
int io_bits;
|
||||
|
||||
lsampl_t maxdata; /* if maxdata==0, use list */
|
||||
const lsampl_t *maxdata_list; /* list is channel specific */
|
||||
unsigned int maxdata; /* if maxdata==0, use list */
|
||||
const unsigned int *maxdata_list; /* list is channel specific */
|
||||
|
||||
unsigned int flags;
|
||||
const unsigned int *flaglist;
|
||||
|
||||
unsigned int settling_time_0;
|
||||
|
||||
const comedi_lrange *range_table;
|
||||
const comedi_lrange *const *range_table_list;
|
||||
const struct comedi_lrange *range_table;
|
||||
const struct comedi_lrange *const *range_table_list;
|
||||
|
||||
unsigned int *chanlist; /* driver-owned chanlist (not used) */
|
||||
|
||||
int (*insn_read) (comedi_device *, comedi_subdevice *, comedi_insn *,
|
||||
lsampl_t *);
|
||||
int (*insn_write) (comedi_device *, comedi_subdevice *, comedi_insn *,
|
||||
lsampl_t *);
|
||||
int (*insn_bits) (comedi_device *, comedi_subdevice *, comedi_insn *,
|
||||
lsampl_t *);
|
||||
int (*insn_config) (comedi_device *, comedi_subdevice *, comedi_insn *,
|
||||
lsampl_t *);
|
||||
int (*insn_read) (struct comedi_device *, struct comedi_subdevice *, struct comedi_insn *,
|
||||
unsigned int *);
|
||||
int (*insn_write) (struct comedi_device *, struct comedi_subdevice *, struct comedi_insn *,
|
||||
unsigned int *);
|
||||
int (*insn_bits) (struct comedi_device *, struct comedi_subdevice *, struct comedi_insn *,
|
||||
unsigned int *);
|
||||
int (*insn_config) (struct comedi_device *, struct comedi_subdevice *, struct comedi_insn *,
|
||||
unsigned int *);
|
||||
|
||||
int (*do_cmd) (comedi_device *, comedi_subdevice *);
|
||||
int (*do_cmdtest) (comedi_device *, comedi_subdevice *, comedi_cmd *);
|
||||
int (*poll) (comedi_device *, comedi_subdevice *);
|
||||
int (*cancel) (comedi_device *, comedi_subdevice *);
|
||||
/* int (*do_lock)(comedi_device *,comedi_subdevice *); */
|
||||
/* int (*do_unlock)(comedi_device *,comedi_subdevice *); */
|
||||
int (*do_cmd) (struct comedi_device *, struct comedi_subdevice *);
|
||||
int (*do_cmdtest) (struct comedi_device *, struct comedi_subdevice *, struct comedi_cmd *);
|
||||
int (*poll) (struct comedi_device *, struct comedi_subdevice *);
|
||||
int (*cancel) (struct comedi_device *, struct comedi_subdevice *);
|
||||
/* int (*do_lock)(struct comedi_device *,struct comedi_subdevice *); */
|
||||
/* int (*do_unlock)(struct comedi_device *,struct comedi_subdevice *); */
|
||||
|
||||
/* called when the buffer changes */
|
||||
int (*buf_change) (comedi_device *dev, comedi_subdevice *s,
|
||||
int (*buf_change) (struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
unsigned long new_size);
|
||||
|
||||
void (*munge) (comedi_device *dev, comedi_subdevice *s, void *data,
|
||||
void (*munge) (struct comedi_device *dev, struct comedi_subdevice *s, void *data,
|
||||
unsigned int num_bytes, unsigned int start_chan_index);
|
||||
enum dma_data_direction async_dma_dir;
|
||||
|
||||
unsigned int state;
|
||||
|
||||
device_create_result_type *class_dev;
|
||||
struct device *class_dev;
|
||||
int minor;
|
||||
};
|
||||
|
||||
|
@ -201,8 +190,8 @@ struct comedi_buf_page {
|
|||
dma_addr_t dma_addr;
|
||||
};
|
||||
|
||||
struct comedi_async_struct {
|
||||
comedi_subdevice *subdevice;
|
||||
struct comedi_async {
|
||||
struct comedi_subdevice *subdevice;
|
||||
|
||||
void *prealloc_buf; /* pre-allocated buffer */
|
||||
unsigned int prealloc_bufsz; /* buffer size, in bytes */
|
||||
|
@ -232,7 +221,7 @@ struct comedi_async_struct {
|
|||
|
||||
unsigned int events; /* events that have occurred */
|
||||
|
||||
comedi_cmd cmd;
|
||||
struct comedi_cmd cmd;
|
||||
|
||||
wait_queue_head_t wait_head;
|
||||
|
||||
|
@ -241,17 +230,17 @@ struct comedi_async_struct {
|
|||
int (*cb_func) (unsigned int flags, void *);
|
||||
void *cb_arg;
|
||||
|
||||
int (*inttrig) (comedi_device *dev, comedi_subdevice *s,
|
||||
int (*inttrig) (struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
unsigned int x);
|
||||
};
|
||||
|
||||
struct comedi_driver_struct {
|
||||
struct comedi_driver_struct *next;
|
||||
struct comedi_driver {
|
||||
struct comedi_driver *next;
|
||||
|
||||
const char *driver_name;
|
||||
struct module *module;
|
||||
int (*attach) (comedi_device *, comedi_devconfig *);
|
||||
int (*detach) (comedi_device *);
|
||||
int (*attach) (struct comedi_device *, struct comedi_devconfig *);
|
||||
int (*detach) (struct comedi_device *);
|
||||
|
||||
/* number of elements in board_name and board_id arrays */
|
||||
unsigned int num_names;
|
||||
|
@ -260,12 +249,12 @@ struct comedi_driver_struct {
|
|||
int offset;
|
||||
};
|
||||
|
||||
struct comedi_device_struct {
|
||||
struct comedi_device {
|
||||
int use_count;
|
||||
comedi_driver *driver;
|
||||
struct comedi_driver *driver;
|
||||
void *private;
|
||||
|
||||
device_create_result_type *class_dev;
|
||||
struct device *class_dev;
|
||||
int minor;
|
||||
/* hw_dev is passed to dma_alloc_coherent when allocating async buffers
|
||||
* for subdevices that have async_dma_dir set to something other than
|
||||
|
@ -281,25 +270,25 @@ struct comedi_device_struct {
|
|||
int in_request_module;
|
||||
|
||||
int n_subdevices;
|
||||
comedi_subdevice *subdevices;
|
||||
struct comedi_subdevice *subdevices;
|
||||
|
||||
/* dumb */
|
||||
unsigned long iobase;
|
||||
unsigned int irq;
|
||||
|
||||
comedi_subdevice *read_subdev;
|
||||
comedi_subdevice *write_subdev;
|
||||
struct comedi_subdevice *read_subdev;
|
||||
struct comedi_subdevice *write_subdev;
|
||||
|
||||
struct fasync_struct *async_queue;
|
||||
|
||||
void (*open) (comedi_device *dev);
|
||||
void (*close) (comedi_device *dev);
|
||||
void (*open) (struct comedi_device *dev);
|
||||
void (*close) (struct comedi_device *dev);
|
||||
};
|
||||
|
||||
struct comedi_device_file_info {
|
||||
comedi_device *device;
|
||||
comedi_subdevice *read_subdevice;
|
||||
comedi_subdevice *write_subdevice;
|
||||
struct comedi_device *device;
|
||||
struct comedi_subdevice *read_subdevice;
|
||||
struct comedi_subdevice *write_subdevice;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_COMEDI_DEBUG
|
||||
|
@ -312,8 +301,8 @@ static const int comedi_debug;
|
|||
* function prototypes
|
||||
*/
|
||||
|
||||
void comedi_event(comedi_device *dev, comedi_subdevice *s);
|
||||
void comedi_error(const comedi_device *dev, const char *s);
|
||||
void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s);
|
||||
void comedi_error(const struct comedi_device *dev, const char *s);
|
||||
|
||||
/* we can expand the number of bits used to encode devices/subdevices into
|
||||
the minor number soon, after more distros support > 8 bit minor numbers
|
||||
|
@ -327,7 +316,7 @@ static const unsigned COMEDI_SUBDEVICE_MINOR_OFFSET = 1;
|
|||
|
||||
struct comedi_device_file_info *comedi_get_device_file_info(unsigned minor);
|
||||
|
||||
static inline comedi_subdevice *comedi_get_read_subdevice(
|
||||
static inline struct comedi_subdevice *comedi_get_read_subdevice(
|
||||
const struct comedi_device_file_info *info)
|
||||
{
|
||||
if (info->read_subdevice)
|
||||
|
@ -337,7 +326,7 @@ static inline comedi_subdevice *comedi_get_read_subdevice(
|
|||
return info->device->read_subdev;
|
||||
}
|
||||
|
||||
static inline comedi_subdevice *comedi_get_write_subdevice(
|
||||
static inline struct comedi_subdevice *comedi_get_write_subdevice(
|
||||
const struct comedi_device_file_info *info)
|
||||
{
|
||||
if (info->write_subdevice)
|
||||
|
@ -347,17 +336,17 @@ static inline comedi_subdevice *comedi_get_write_subdevice(
|
|||
return info->device->write_subdev;
|
||||
}
|
||||
|
||||
void comedi_device_detach(comedi_device *dev);
|
||||
int comedi_device_attach(comedi_device *dev, comedi_devconfig *it);
|
||||
int comedi_driver_register(comedi_driver *);
|
||||
int comedi_driver_unregister(comedi_driver *);
|
||||
void comedi_device_detach(struct comedi_device *dev);
|
||||
int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
int comedi_driver_register(struct comedi_driver *);
|
||||
int comedi_driver_unregister(struct comedi_driver *);
|
||||
|
||||
void init_polling(void);
|
||||
void cleanup_polling(void);
|
||||
void start_polling(comedi_device *);
|
||||
void stop_polling(comedi_device *);
|
||||
void start_polling(struct comedi_device *);
|
||||
void stop_polling(struct comedi_device *);
|
||||
|
||||
int comedi_buf_alloc(comedi_device *dev, comedi_subdevice *s, unsigned long
|
||||
int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long
|
||||
new_size);
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
|
@ -386,13 +375,13 @@ enum subdevice_runflags {
|
|||
various internal comedi functions
|
||||
*/
|
||||
|
||||
int do_rangeinfo_ioctl(comedi_device *dev, comedi_rangeinfo *arg);
|
||||
int check_chanlist(comedi_subdevice *s, int n, unsigned int *chanlist);
|
||||
void comedi_set_subdevice_runflags(comedi_subdevice *s, unsigned mask,
|
||||
int do_rangeinfo_ioctl(struct comedi_device *dev, struct comedi_rangeinfo *arg);
|
||||
int check_chanlist(struct comedi_subdevice *s, int n, unsigned int *chanlist);
|
||||
void comedi_set_subdevice_runflags(struct comedi_subdevice *s, unsigned mask,
|
||||
unsigned bits);
|
||||
unsigned comedi_get_subdevice_runflags(comedi_subdevice *s);
|
||||
int insn_inval(comedi_device *dev, comedi_subdevice *s,
|
||||
comedi_insn *insn, lsampl_t *data);
|
||||
unsigned comedi_get_subdevice_runflags(struct comedi_subdevice *s);
|
||||
int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
/* range stuff */
|
||||
|
||||
|
@ -403,12 +392,12 @@ int insn_inval(comedi_device *dev, comedi_subdevice *s,
|
|||
#define BIP_RANGE(a) {-(a)*1e6, (a)*1e6, 0}
|
||||
#define UNI_RANGE(a) {0, (a)*1e6, 0}
|
||||
|
||||
extern const comedi_lrange range_bipolar10;
|
||||
extern const comedi_lrange range_bipolar5;
|
||||
extern const comedi_lrange range_bipolar2_5;
|
||||
extern const comedi_lrange range_unipolar10;
|
||||
extern const comedi_lrange range_unipolar5;
|
||||
extern const comedi_lrange range_unknown;
|
||||
extern const struct comedi_lrange range_bipolar10;
|
||||
extern const struct comedi_lrange range_bipolar5;
|
||||
extern const struct comedi_lrange range_bipolar2_5;
|
||||
extern const struct comedi_lrange range_unipolar10;
|
||||
extern const struct comedi_lrange range_unipolar5;
|
||||
extern const struct comedi_lrange range_unknown;
|
||||
|
||||
#define range_digital range_unipolar5
|
||||
|
||||
|
@ -418,21 +407,21 @@ extern const comedi_lrange range_unknown;
|
|||
#define GCC_ZERO_LENGTH_ARRAY 0
|
||||
#endif
|
||||
|
||||
struct comedi_lrange_struct {
|
||||
struct comedi_lrange {
|
||||
int length;
|
||||
comedi_krange range[GCC_ZERO_LENGTH_ARRAY];
|
||||
struct comedi_krange range[GCC_ZERO_LENGTH_ARRAY];
|
||||
};
|
||||
|
||||
/* some silly little inline functions */
|
||||
|
||||
static inline int alloc_subdevices(comedi_device *dev,
|
||||
static inline int alloc_subdevices(struct comedi_device *dev,
|
||||
unsigned int num_subdevices)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
dev->n_subdevices = num_subdevices;
|
||||
dev->subdevices =
|
||||
kcalloc(num_subdevices, sizeof(comedi_subdevice), GFP_KERNEL);
|
||||
kcalloc(num_subdevices, sizeof(struct comedi_subdevice), GFP_KERNEL);
|
||||
if (!dev->subdevices)
|
||||
return -ENOMEM;
|
||||
for (i = 0; i < num_subdevices; ++i) {
|
||||
|
@ -444,7 +433,7 @@ static inline int alloc_subdevices(comedi_device *dev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline int alloc_private(comedi_device *dev, int size)
|
||||
static inline int alloc_private(struct comedi_device *dev, int size)
|
||||
{
|
||||
dev->private = kzalloc(size, GFP_KERNEL);
|
||||
if (!dev->private)
|
||||
|
@ -452,17 +441,17 @@ static inline int alloc_private(comedi_device *dev, int size)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline unsigned int bytes_per_sample(const comedi_subdevice *subd)
|
||||
static inline unsigned int bytes_per_sample(const struct comedi_subdevice *subd)
|
||||
{
|
||||
if (subd->subdev_flags & SDF_LSAMPL)
|
||||
return sizeof(lsampl_t);
|
||||
return sizeof(unsigned int);
|
||||
else
|
||||
return sizeof(sampl_t);
|
||||
return sizeof(short);
|
||||
}
|
||||
|
||||
/* must be used in attach to set dev->hw_dev if you wish to dma directly
|
||||
into comedi's buffer */
|
||||
static inline void comedi_set_hw_dev(comedi_device *dev, struct device *hw_dev)
|
||||
static inline void comedi_set_hw_dev(struct comedi_device *dev, struct device *hw_dev)
|
||||
{
|
||||
if (dev->hw_dev)
|
||||
put_device(dev->hw_dev);
|
||||
|
@ -474,31 +463,31 @@ static inline void comedi_set_hw_dev(comedi_device *dev, struct device *hw_dev)
|
|||
}
|
||||
}
|
||||
|
||||
int comedi_buf_put(comedi_async *async, sampl_t x);
|
||||
int comedi_buf_get(comedi_async *async, sampl_t *x);
|
||||
int comedi_buf_put(struct comedi_async *async, short x);
|
||||
int comedi_buf_get(struct comedi_async *async, short *x);
|
||||
|
||||
unsigned int comedi_buf_write_n_available(comedi_async *async);
|
||||
unsigned int comedi_buf_write_alloc(comedi_async *async, unsigned int nbytes);
|
||||
unsigned int comedi_buf_write_alloc_strict(comedi_async *async,
|
||||
unsigned int comedi_buf_write_n_available(struct comedi_async *async);
|
||||
unsigned int comedi_buf_write_alloc(struct comedi_async *async, unsigned int nbytes);
|
||||
unsigned int comedi_buf_write_alloc_strict(struct comedi_async *async,
|
||||
unsigned int nbytes);
|
||||
unsigned comedi_buf_write_free(comedi_async *async, unsigned int nbytes);
|
||||
unsigned comedi_buf_read_alloc(comedi_async *async, unsigned nbytes);
|
||||
unsigned comedi_buf_read_free(comedi_async *async, unsigned int nbytes);
|
||||
unsigned int comedi_buf_read_n_available(comedi_async *async);
|
||||
void comedi_buf_memcpy_to(comedi_async *async, unsigned int offset,
|
||||
unsigned comedi_buf_write_free(struct comedi_async *async, unsigned int nbytes);
|
||||
unsigned comedi_buf_read_alloc(struct comedi_async *async, unsigned nbytes);
|
||||
unsigned comedi_buf_read_free(struct comedi_async *async, unsigned int nbytes);
|
||||
unsigned int comedi_buf_read_n_available(struct comedi_async *async);
|
||||
void comedi_buf_memcpy_to(struct comedi_async *async, unsigned int offset,
|
||||
const void *source, unsigned int num_bytes);
|
||||
void comedi_buf_memcpy_from(comedi_async *async, unsigned int offset,
|
||||
void comedi_buf_memcpy_from(struct comedi_async *async, unsigned int offset,
|
||||
void *destination, unsigned int num_bytes);
|
||||
static inline unsigned comedi_buf_write_n_allocated(comedi_async *async)
|
||||
static inline unsigned comedi_buf_write_n_allocated(struct comedi_async *async)
|
||||
{
|
||||
return async->buf_write_alloc_count - async->buf_write_count;
|
||||
}
|
||||
static inline unsigned comedi_buf_read_n_allocated(comedi_async *async)
|
||||
static inline unsigned comedi_buf_read_n_allocated(struct comedi_async *async)
|
||||
{
|
||||
return async->buf_read_alloc_count - async->buf_read_count;
|
||||
}
|
||||
|
||||
void comedi_reset_async_buf(comedi_async *async);
|
||||
void comedi_reset_async_buf(struct comedi_async *async);
|
||||
|
||||
static inline void *comedi_aux_data(int options[], int n)
|
||||
{
|
||||
|
@ -527,10 +516,13 @@ static inline void *comedi_aux_data(int options[], int n)
|
|||
|
||||
int comedi_alloc_board_minor(struct device *hardware_device);
|
||||
void comedi_free_board_minor(unsigned minor);
|
||||
int comedi_alloc_subdevice_minor(comedi_device *dev, comedi_subdevice *s);
|
||||
void comedi_free_subdevice_minor(comedi_subdevice *s);
|
||||
int comedi_alloc_subdevice_minor(struct comedi_device *dev, struct comedi_subdevice *s);
|
||||
void comedi_free_subdevice_minor(struct comedi_subdevice *s);
|
||||
int comedi_pci_auto_config(struct pci_dev *pcidev, const char *board_name);
|
||||
void comedi_pci_auto_unconfig(struct pci_dev *pcidev);
|
||||
struct usb_device; /* forward declaration */
|
||||
int comedi_usb_auto_config(struct usb_device *usbdev, const char *board_name);
|
||||
void comedi_usb_auto_unconfig(struct usb_device *usbdev);
|
||||
|
||||
#include "comedi_rt.h"
|
||||
|
||||
|
|
|
@ -36,18 +36,16 @@
|
|||
|
||||
#ifndef KCOMEDILIB_DEPRECATED
|
||||
|
||||
typedef void comedi_t;
|
||||
|
||||
/* these functions may not be called at real-time priority */
|
||||
|
||||
comedi_t *comedi_open(const char *path);
|
||||
int comedi_close(comedi_t *dev);
|
||||
void *comedi_open(const char *path);
|
||||
int comedi_close(void *dev);
|
||||
|
||||
/* these functions may be called at any priority, but may fail at
|
||||
real-time priority */
|
||||
|
||||
int comedi_lock(comedi_t *dev, unsigned int subdev);
|
||||
int comedi_unlock(comedi_t *dev, unsigned int subdev);
|
||||
int comedi_lock(void *dev, unsigned int subdev);
|
||||
int comedi_unlock(void *dev, unsigned int subdev);
|
||||
|
||||
/* these functions may be called at any priority, but you must hold
|
||||
the lock for the subdevice */
|
||||
|
@ -56,68 +54,68 @@ int comedi_loglevel(int loglevel);
|
|||
void comedi_perror(const char *s);
|
||||
char *comedi_strerror(int errnum);
|
||||
int comedi_errno(void);
|
||||
int comedi_fileno(comedi_t *dev);
|
||||
int comedi_fileno(void *dev);
|
||||
|
||||
int comedi_cancel(comedi_t *dev, unsigned int subdev);
|
||||
int comedi_register_callback(comedi_t *dev, unsigned int subdev,
|
||||
int comedi_cancel(void *dev, unsigned int subdev);
|
||||
int comedi_register_callback(void *dev, unsigned int subdev,
|
||||
unsigned int mask, int (*cb) (unsigned int, void *), void *arg);
|
||||
|
||||
int comedi_command(comedi_t *dev, comedi_cmd *cmd);
|
||||
int comedi_command_test(comedi_t *dev, comedi_cmd *cmd);
|
||||
int comedi_trigger(comedi_t *dev, unsigned int subdev, comedi_trig *it);
|
||||
int __comedi_trigger(comedi_t *dev, unsigned int subdev, comedi_trig *it);
|
||||
int comedi_data_write(comedi_t *dev, unsigned int subdev, unsigned int chan,
|
||||
unsigned int range, unsigned int aref, lsampl_t data);
|
||||
int comedi_data_read(comedi_t *dev, unsigned int subdev, unsigned int chan,
|
||||
unsigned int range, unsigned int aref, lsampl_t *data);
|
||||
int comedi_data_read_hint(comedi_t *dev, unsigned int subdev,
|
||||
int comedi_command(void *dev, struct comedi_cmd *cmd);
|
||||
int comedi_command_test(void *dev, struct comedi_cmd *cmd);
|
||||
int comedi_trigger(void *dev, unsigned int subdev, struct comedi_trig *it);
|
||||
int __comedi_trigger(void *dev, unsigned int subdev, struct comedi_trig *it);
|
||||
int comedi_data_write(void *dev, unsigned int subdev, unsigned int chan,
|
||||
unsigned int range, unsigned int aref, unsigned int data);
|
||||
int comedi_data_read(void *dev, unsigned int subdev, unsigned int chan,
|
||||
unsigned int range, unsigned int aref, unsigned int *data);
|
||||
int comedi_data_read_hint(void *dev, unsigned int subdev,
|
||||
unsigned int chan, unsigned int range, unsigned int aref);
|
||||
int comedi_data_read_delayed(comedi_t *dev, unsigned int subdev,
|
||||
int comedi_data_read_delayed(void *dev, unsigned int subdev,
|
||||
unsigned int chan, unsigned int range, unsigned int aref,
|
||||
lsampl_t *data, unsigned int nano_sec);
|
||||
int comedi_dio_config(comedi_t *dev, unsigned int subdev, unsigned int chan,
|
||||
unsigned int *data, unsigned int nano_sec);
|
||||
int comedi_dio_config(void *dev, unsigned int subdev, unsigned int chan,
|
||||
unsigned int io);
|
||||
int comedi_dio_read(comedi_t *dev, unsigned int subdev, unsigned int chan,
|
||||
int comedi_dio_read(void *dev, unsigned int subdev, unsigned int chan,
|
||||
unsigned int *val);
|
||||
int comedi_dio_write(comedi_t *dev, unsigned int subdev, unsigned int chan,
|
||||
int comedi_dio_write(void *dev, unsigned int subdev, unsigned int chan,
|
||||
unsigned int val);
|
||||
int comedi_dio_bitfield(comedi_t *dev, unsigned int subdev, unsigned int mask,
|
||||
int comedi_dio_bitfield(void *dev, unsigned int subdev, unsigned int mask,
|
||||
unsigned int *bits);
|
||||
int comedi_get_n_subdevices(comedi_t *dev);
|
||||
int comedi_get_version_code(comedi_t *dev);
|
||||
const char *comedi_get_driver_name(comedi_t *dev);
|
||||
const char *comedi_get_board_name(comedi_t *dev);
|
||||
int comedi_get_subdevice_type(comedi_t *dev, unsigned int subdevice);
|
||||
int comedi_find_subdevice_by_type(comedi_t *dev, int type, unsigned int subd);
|
||||
int comedi_get_n_channels(comedi_t *dev, unsigned int subdevice);
|
||||
lsampl_t comedi_get_maxdata(comedi_t *dev, unsigned int subdevice, unsigned
|
||||
int comedi_get_n_subdevices(void *dev);
|
||||
int comedi_get_version_code(void *dev);
|
||||
const char *comedi_get_driver_name(void *dev);
|
||||
const char *comedi_get_board_name(void *dev);
|
||||
int comedi_get_subdevice_type(void *dev, unsigned int subdevice);
|
||||
int comedi_find_subdevice_by_type(void *dev, int type, unsigned int subd);
|
||||
int comedi_get_n_channels(void *dev, unsigned int subdevice);
|
||||
unsigned int comedi_get_maxdata(void *dev, unsigned int subdevice, unsigned
|
||||
int chan);
|
||||
int comedi_get_n_ranges(comedi_t *dev, unsigned int subdevice, unsigned int
|
||||
int comedi_get_n_ranges(void *dev, unsigned int subdevice, unsigned int
|
||||
chan);
|
||||
int comedi_do_insn(comedi_t *dev, comedi_insn *insn);
|
||||
int comedi_poll(comedi_t *dev, unsigned int subdev);
|
||||
int comedi_do_insn(void *dev, struct comedi_insn *insn);
|
||||
int comedi_poll(void *dev, unsigned int subdev);
|
||||
|
||||
/* DEPRECATED functions */
|
||||
int comedi_get_rangetype(comedi_t *dev, unsigned int subdevice,
|
||||
int comedi_get_rangetype(void *dev, unsigned int subdevice,
|
||||
unsigned int chan);
|
||||
|
||||
/* ALPHA functions */
|
||||
unsigned int comedi_get_subdevice_flags(comedi_t *dev, unsigned int subdevice);
|
||||
int comedi_get_len_chanlist(comedi_t *dev, unsigned int subdevice);
|
||||
int comedi_get_krange(comedi_t *dev, unsigned int subdevice, unsigned int
|
||||
chan, unsigned int range, comedi_krange *krange);
|
||||
unsigned int comedi_get_buf_head_pos(comedi_t *dev, unsigned int subdevice);
|
||||
int comedi_set_user_int_count(comedi_t *dev, unsigned int subdevice,
|
||||
unsigned int comedi_get_subdevice_flags(void *dev, unsigned int subdevice);
|
||||
int comedi_get_len_chanlist(void *dev, unsigned int subdevice);
|
||||
int comedi_get_krange(void *dev, unsigned int subdevice, unsigned int
|
||||
chan, unsigned int range, struct comedi_krange *krange);
|
||||
unsigned int comedi_get_buf_head_pos(void *dev, unsigned int subdevice);
|
||||
int comedi_set_user_int_count(void *dev, unsigned int subdevice,
|
||||
unsigned int buf_user_count);
|
||||
int comedi_map(comedi_t *dev, unsigned int subdev, void *ptr);
|
||||
int comedi_unmap(comedi_t *dev, unsigned int subdev);
|
||||
int comedi_get_buffer_size(comedi_t *dev, unsigned int subdev);
|
||||
int comedi_mark_buffer_read(comedi_t *dev, unsigned int subdevice,
|
||||
int comedi_map(void *dev, unsigned int subdev, void *ptr);
|
||||
int comedi_unmap(void *dev, unsigned int subdev);
|
||||
int comedi_get_buffer_size(void *dev, unsigned int subdev);
|
||||
int comedi_mark_buffer_read(void *dev, unsigned int subdevice,
|
||||
unsigned int num_bytes);
|
||||
int comedi_mark_buffer_written(comedi_t *d, unsigned int subdevice,
|
||||
int comedi_mark_buffer_written(void *d, unsigned int subdevice,
|
||||
unsigned int num_bytes);
|
||||
int comedi_get_buffer_contents(comedi_t *dev, unsigned int subdevice);
|
||||
int comedi_get_buffer_offset(comedi_t *dev, unsigned int subdevice);
|
||||
int comedi_get_buffer_contents(void *dev, unsigned int subdevice);
|
||||
int comedi_get_buffer_offset(void *dev, unsigned int subdevice);
|
||||
|
||||
#else
|
||||
|
||||
|
@ -139,14 +137,14 @@ int comedi_cancel(unsigned int minor, unsigned int subdev);
|
|||
int comedi_register_callback(unsigned int minor, unsigned int subdev,
|
||||
unsigned int mask, int (*cb) (unsigned int, void *), void *arg);
|
||||
|
||||
int comedi_command(unsigned int minor, comedi_cmd *cmd);
|
||||
int comedi_command_test(unsigned int minor, comedi_cmd *cmd);
|
||||
int comedi_trigger(unsigned int minor, unsigned int subdev, comedi_trig *it);
|
||||
int __comedi_trigger(unsigned int minor, unsigned int subdev, comedi_trig *it);
|
||||
int comedi_command(unsigned int minor, struct comedi_cmd *cmd);
|
||||
int comedi_command_test(unsigned int minor, struct comedi_cmd *cmd);
|
||||
int comedi_trigger(unsigned int minor, unsigned int subdev, struct comedi_trig *it);
|
||||
int __comedi_trigger(unsigned int minor, unsigned int subdev, struct comedi_trig *it);
|
||||
int comedi_data_write(unsigned int dev, unsigned int subdev, unsigned int chan,
|
||||
unsigned int range, unsigned int aref, lsampl_t data);
|
||||
unsigned int range, unsigned int aref, unsigned int data);
|
||||
int comedi_data_read(unsigned int dev, unsigned int subdev, unsigned int chan,
|
||||
unsigned int range, unsigned int aref, lsampl_t *data);
|
||||
unsigned int range, unsigned int aref, unsigned int *data);
|
||||
int comedi_dio_config(unsigned int dev, unsigned int subdev, unsigned int chan,
|
||||
unsigned int io);
|
||||
int comedi_dio_read(unsigned int dev, unsigned int subdev, unsigned int chan,
|
||||
|
@ -163,11 +161,11 @@ int comedi_get_subdevice_type(unsigned int minor, unsigned int subdevice);
|
|||
int comedi_find_subdevice_by_type(unsigned int minor, int type,
|
||||
unsigned int subd);
|
||||
int comedi_get_n_channels(unsigned int minor, unsigned int subdevice);
|
||||
lsampl_t comedi_get_maxdata(unsigned int minor, unsigned int subdevice, unsigned
|
||||
unsigned int comedi_get_maxdata(unsigned int minor, unsigned int subdevice, unsigned
|
||||
int chan);
|
||||
int comedi_get_n_ranges(unsigned int minor, unsigned int subdevice, unsigned int
|
||||
chan);
|
||||
int comedi_do_insn(unsigned int minor, comedi_insn *insn);
|
||||
int comedi_do_insn(unsigned int minor, struct comedi_insn *insn);
|
||||
int comedi_poll(unsigned int minor, unsigned int subdev);
|
||||
|
||||
/* DEPRECATED functions */
|
||||
|
@ -179,7 +177,7 @@ unsigned int comedi_get_subdevice_flags(unsigned int minor, unsigned int
|
|||
subdevice);
|
||||
int comedi_get_len_chanlist(unsigned int minor, unsigned int subdevice);
|
||||
int comedi_get_krange(unsigned int minor, unsigned int subdevice, unsigned int
|
||||
chan, unsigned int range, comedi_krange *krange);
|
||||
chan, unsigned int range, struct comedi_krange *krange);
|
||||
unsigned int comedi_get_buf_head_pos(unsigned int minor, unsigned int
|
||||
subdevice);
|
||||
int comedi_set_user_int_count(unsigned int minor, unsigned int subdevice,
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
|
@ -46,26 +47,26 @@
|
|||
#include <asm/io.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
static int postconfig(comedi_device * dev);
|
||||
static int insn_rw_emulate_bits(comedi_device * dev, comedi_subdevice * s,
|
||||
comedi_insn * insn, lsampl_t * data);
|
||||
static void *comedi_recognize(comedi_driver * driv, const char *name);
|
||||
static void comedi_report_boards(comedi_driver * driv);
|
||||
static int poll_invalid(comedi_device * dev, comedi_subdevice * s);
|
||||
int comedi_buf_alloc(comedi_device * dev, comedi_subdevice * s,
|
||||
static int postconfig(struct comedi_device *dev);
|
||||
static int insn_rw_emulate_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static void *comedi_recognize(struct comedi_driver * driv, const char *name);
|
||||
static void comedi_report_boards(struct comedi_driver *driv);
|
||||
static int poll_invalid(struct comedi_device *dev, struct comedi_subdevice *s);
|
||||
int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
unsigned long new_size);
|
||||
|
||||
comedi_driver *comedi_drivers;
|
||||
struct comedi_driver *comedi_drivers;
|
||||
|
||||
int comedi_modprobe(int minor)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static void cleanup_device(comedi_device * dev)
|
||||
static void cleanup_device(struct comedi_device *dev)
|
||||
{
|
||||
int i;
|
||||
comedi_subdevice *s;
|
||||
struct comedi_subdevice *s;
|
||||
|
||||
if (dev->subdevices) {
|
||||
for (i = 0; i < dev->n_subdevices; i++) {
|
||||
|
@ -80,10 +81,8 @@ static void cleanup_device(comedi_device * dev)
|
|||
dev->subdevices = NULL;
|
||||
dev->n_subdevices = 0;
|
||||
}
|
||||
if (dev->private) {
|
||||
kfree(dev->private);
|
||||
dev->private = NULL;
|
||||
}
|
||||
kfree(dev->private);
|
||||
dev->private = NULL;
|
||||
dev->driver = 0;
|
||||
dev->board_name = NULL;
|
||||
dev->board_ptr = NULL;
|
||||
|
@ -96,7 +95,7 @@ static void cleanup_device(comedi_device * dev)
|
|||
comedi_set_hw_dev(dev, NULL);
|
||||
}
|
||||
|
||||
static void __comedi_device_detach(comedi_device * dev)
|
||||
static void __comedi_device_detach(struct comedi_device *dev)
|
||||
{
|
||||
dev->attached = 0;
|
||||
if (dev->driver) {
|
||||
|
@ -107,16 +106,16 @@ static void __comedi_device_detach(comedi_device * dev)
|
|||
cleanup_device(dev);
|
||||
}
|
||||
|
||||
void comedi_device_detach(comedi_device * dev)
|
||||
void comedi_device_detach(struct comedi_device *dev)
|
||||
{
|
||||
if (!dev->attached)
|
||||
return;
|
||||
__comedi_device_detach(dev);
|
||||
}
|
||||
|
||||
int comedi_device_attach(comedi_device * dev, comedi_devconfig * it)
|
||||
int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
{
|
||||
comedi_driver *driv;
|
||||
struct comedi_driver *driv;
|
||||
int ret;
|
||||
|
||||
if (dev->attached)
|
||||
|
@ -139,7 +138,7 @@ int comedi_device_attach(comedi_device * dev, comedi_devconfig * it)
|
|||
continue;
|
||||
}
|
||||
}
|
||||
//initialize dev->driver here so comedi_error() can be called from attach
|
||||
/* initialize dev->driver here so comedi_error() can be called from attach */
|
||||
dev->driver = driv;
|
||||
ret = driv->attach(dev, it);
|
||||
if (ret < 0) {
|
||||
|
@ -150,8 +149,8 @@ int comedi_device_attach(comedi_device * dev, comedi_devconfig * it)
|
|||
goto attached;
|
||||
}
|
||||
|
||||
// recognize has failed if we get here
|
||||
// report valid board names before returning error
|
||||
/* recognize has failed if we get here */
|
||||
/* report valid board names before returning error */
|
||||
for (driv = comedi_drivers; driv; driv = driv->next) {
|
||||
if (!try_module_get(driv->module)) {
|
||||
printk("comedi: failed to increment module count\n");
|
||||
|
@ -181,7 +180,7 @@ attached:
|
|||
return 0;
|
||||
}
|
||||
|
||||
int comedi_driver_register(comedi_driver * driver)
|
||||
int comedi_driver_register(struct comedi_driver *driver)
|
||||
{
|
||||
driver->next = comedi_drivers;
|
||||
comedi_drivers = driver;
|
||||
|
@ -189,15 +188,15 @@ int comedi_driver_register(comedi_driver * driver)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int comedi_driver_unregister(comedi_driver * driver)
|
||||
int comedi_driver_unregister(struct comedi_driver *driver)
|
||||
{
|
||||
comedi_driver *prev;
|
||||
struct comedi_driver *prev;
|
||||
int i;
|
||||
|
||||
/* check for devices using this driver */
|
||||
for (i = 0; i < COMEDI_NUM_BOARD_MINORS; i++) {
|
||||
struct comedi_device_file_info *dev_file_info = comedi_get_device_file_info(i);
|
||||
comedi_device *dev;
|
||||
struct comedi_device *dev;
|
||||
|
||||
if(dev_file_info == NULL) continue;
|
||||
dev = dev_file_info->device;
|
||||
|
@ -225,11 +224,11 @@ int comedi_driver_unregister(comedi_driver * driver)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int postconfig(comedi_device * dev)
|
||||
static int postconfig(struct comedi_device *dev)
|
||||
{
|
||||
int i;
|
||||
comedi_subdevice *s;
|
||||
comedi_async *async = NULL;
|
||||
struct comedi_subdevice *s;
|
||||
struct comedi_async *async = NULL;
|
||||
int ret;
|
||||
|
||||
for (i = 0; i < dev->n_subdevices; i++) {
|
||||
|
@ -246,7 +245,7 @@ static int postconfig(comedi_device * dev)
|
|||
SDF_CMD_WRITE)) == 0);
|
||||
BUG_ON(!s->do_cmdtest);
|
||||
|
||||
async = kzalloc(sizeof(comedi_async), GFP_KERNEL);
|
||||
async = kzalloc(sizeof(struct comedi_async), GFP_KERNEL);
|
||||
if (async == NULL) {
|
||||
printk("failed to allocate async struct\n");
|
||||
return -ENOMEM;
|
||||
|
@ -298,8 +297,8 @@ static int postconfig(comedi_device * dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// generic recognize function for drivers that register their supported board names
|
||||
void *comedi_recognize(comedi_driver * driv, const char *name)
|
||||
/* generic recognize function for drivers that register their supported board names */
|
||||
void *comedi_recognize(struct comedi_driver * driv, const char *name)
|
||||
{
|
||||
unsigned i;
|
||||
const char *const *name_ptr = driv->board_name;
|
||||
|
@ -314,7 +313,7 @@ void *comedi_recognize(comedi_driver * driv, const char *name)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void comedi_report_boards(comedi_driver * driv)
|
||||
void comedi_report_boards(struct comedi_driver *driv)
|
||||
{
|
||||
unsigned int i;
|
||||
const char *const *name_ptr;
|
||||
|
@ -332,28 +331,28 @@ void comedi_report_boards(comedi_driver * driv)
|
|||
printk(" %s\n", driv->driver_name);
|
||||
}
|
||||
|
||||
static int poll_invalid(comedi_device * dev, comedi_subdevice * s)
|
||||
static int poll_invalid(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int insn_inval(comedi_device * dev, comedi_subdevice * s,
|
||||
comedi_insn * insn, lsampl_t * data)
|
||||
int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int insn_rw_emulate_bits(comedi_device * dev, comedi_subdevice * s,
|
||||
comedi_insn * insn, lsampl_t * data)
|
||||
static int insn_rw_emulate_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
comedi_insn new_insn;
|
||||
struct comedi_insn new_insn;
|
||||
int ret;
|
||||
static const unsigned channels_per_bitfield = 32;
|
||||
|
||||
unsigned chan = CR_CHAN(insn->chanspec);
|
||||
const unsigned base_bitfield_channel =
|
||||
(chan < channels_per_bitfield) ? 0 : chan;
|
||||
lsampl_t new_data[2];
|
||||
unsigned int new_data[2];
|
||||
memset(new_data, 0, sizeof(new_data));
|
||||
memset(&new_insn, 0, sizeof(new_insn));
|
||||
new_insn.insn = INSN_BITS;
|
||||
|
@ -380,7 +379,7 @@ static int insn_rw_emulate_bits(comedi_device * dev, comedi_subdevice * s,
|
|||
return 1;
|
||||
}
|
||||
|
||||
static inline unsigned long uvirt_to_kva(pgd_t * pgd, unsigned long adr)
|
||||
static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr)
|
||||
{
|
||||
unsigned long ret = 0UL;
|
||||
pmd_t *pmd;
|
||||
|
@ -413,10 +412,10 @@ static inline unsigned long kvirt_to_kva(unsigned long adr)
|
|||
return kva;
|
||||
}
|
||||
|
||||
int comedi_buf_alloc(comedi_device * dev, comedi_subdevice * s,
|
||||
int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
unsigned long new_size)
|
||||
{
|
||||
comedi_async *async = s->async;
|
||||
struct comedi_async *async = s->async;
|
||||
|
||||
/* Round up new_size to multiple of PAGE_SIZE */
|
||||
new_size = (new_size + PAGE_SIZE - 1) & PAGE_MASK;
|
||||
|
@ -425,7 +424,7 @@ int comedi_buf_alloc(comedi_device * dev, comedi_subdevice * s,
|
|||
if (async->prealloc_buf && async->prealloc_bufsz == new_size) {
|
||||
return 0;
|
||||
}
|
||||
// deallocate old buffer
|
||||
/* deallocate old buffer */
|
||||
if (async->prealloc_buf) {
|
||||
vunmap(async->prealloc_buf);
|
||||
async->prealloc_buf = NULL;
|
||||
|
@ -454,7 +453,7 @@ int comedi_buf_alloc(comedi_device * dev, comedi_subdevice * s,
|
|||
async->buf_page_list = NULL;
|
||||
async->n_buf_pages = 0;
|
||||
}
|
||||
// allocate new buffer
|
||||
/* allocate new buffer */
|
||||
if (new_size) {
|
||||
unsigned i = 0;
|
||||
unsigned n_pages = new_size >> PAGE_SHIFT;
|
||||
|
@ -537,16 +536,15 @@ int comedi_buf_alloc(comedi_device * dev, comedi_subdevice * s,
|
|||
|
||||
/* munging is applied to data by core as it passes between user
|
||||
* and kernel space */
|
||||
unsigned int comedi_buf_munge(comedi_async * async, unsigned int num_bytes)
|
||||
unsigned int comedi_buf_munge(struct comedi_async *async, unsigned int num_bytes)
|
||||
{
|
||||
comedi_subdevice *s = async->subdevice;
|
||||
struct comedi_subdevice *s = async->subdevice;
|
||||
unsigned int count = 0;
|
||||
const unsigned num_sample_bytes = bytes_per_sample(s);
|
||||
|
||||
if (s->munge == NULL || (async->cmd.flags & CMDF_RAWDATA)) {
|
||||
async->munge_count += num_bytes;
|
||||
if ((int)(async->munge_count - async->buf_write_count) > 0)
|
||||
BUG();
|
||||
BUG_ON((int)(async->munge_count - async->buf_write_count) > 0);
|
||||
return num_bytes;
|
||||
}
|
||||
/* don't munge partial samples */
|
||||
|
@ -567,7 +565,7 @@ unsigned int comedi_buf_munge(comedi_async * async, unsigned int num_bytes)
|
|||
s->munge(s->device, s, async->prealloc_buf + async->munge_ptr,
|
||||
block_size, async->munge_chan);
|
||||
|
||||
smp_wmb(); //barrier insures data is munged in buffer before munge_count is incremented
|
||||
smp_wmb(); /* barrier insures data is munged in buffer before munge_count is incremented */
|
||||
|
||||
async->munge_chan += block_size / num_sample_bytes;
|
||||
async->munge_chan %= async->cmd.chanlist_len;
|
||||
|
@ -576,12 +574,11 @@ unsigned int comedi_buf_munge(comedi_async * async, unsigned int num_bytes)
|
|||
async->munge_ptr %= async->prealloc_bufsz;
|
||||
count += block_size;
|
||||
}
|
||||
if ((int)(async->munge_count - async->buf_write_count) > 0)
|
||||
BUG();
|
||||
BUG_ON((int)(async->munge_count - async->buf_write_count) > 0);
|
||||
return count;
|
||||
}
|
||||
|
||||
unsigned int comedi_buf_write_n_available(comedi_async * async)
|
||||
unsigned int comedi_buf_write_n_available(struct comedi_async *async)
|
||||
{
|
||||
unsigned int free_end;
|
||||
unsigned int nbytes;
|
||||
|
@ -601,7 +598,7 @@ unsigned int comedi_buf_write_n_available(comedi_async * async)
|
|||
}
|
||||
|
||||
/* allocates chunk for the writer from free buffer space */
|
||||
unsigned int comedi_buf_write_alloc(comedi_async * async, unsigned int nbytes)
|
||||
unsigned int comedi_buf_write_alloc(struct comedi_async *async, unsigned int nbytes)
|
||||
{
|
||||
unsigned int free_end = async->buf_read_count + async->prealloc_bufsz;
|
||||
|
||||
|
@ -616,7 +613,7 @@ unsigned int comedi_buf_write_alloc(comedi_async * async, unsigned int nbytes)
|
|||
}
|
||||
|
||||
/* allocates nothing unless it can completely fulfill the request */
|
||||
unsigned int comedi_buf_write_alloc_strict(comedi_async * async,
|
||||
unsigned int comedi_buf_write_alloc_strict(struct comedi_async *async,
|
||||
unsigned int nbytes)
|
||||
{
|
||||
unsigned int free_end = async->buf_read_count + async->prealloc_bufsz;
|
||||
|
@ -632,7 +629,7 @@ unsigned int comedi_buf_write_alloc_strict(comedi_async * async,
|
|||
}
|
||||
|
||||
/* transfers a chunk from writer to filled buffer space */
|
||||
unsigned comedi_buf_write_free(comedi_async * async, unsigned int nbytes)
|
||||
unsigned comedi_buf_write_free(struct comedi_async *async, unsigned int nbytes)
|
||||
{
|
||||
if ((int)(async->buf_write_count + nbytes -
|
||||
async->buf_write_alloc_count) > 0) {
|
||||
|
@ -650,7 +647,7 @@ unsigned comedi_buf_write_free(comedi_async * async, unsigned int nbytes)
|
|||
}
|
||||
|
||||
/* allocates a chunk for the reader from filled (and munged) buffer space */
|
||||
unsigned comedi_buf_read_alloc(comedi_async * async, unsigned nbytes)
|
||||
unsigned comedi_buf_read_alloc(struct comedi_async *async, unsigned nbytes)
|
||||
{
|
||||
if ((int)(async->buf_read_alloc_count + nbytes - async->munge_count) >
|
||||
0) {
|
||||
|
@ -664,9 +661,9 @@ unsigned comedi_buf_read_alloc(comedi_async * async, unsigned nbytes)
|
|||
}
|
||||
|
||||
/* transfers control of a chunk from reader to free buffer space */
|
||||
unsigned comedi_buf_read_free(comedi_async * async, unsigned int nbytes)
|
||||
unsigned comedi_buf_read_free(struct comedi_async *async, unsigned int nbytes)
|
||||
{
|
||||
// barrier insures data has been read out of buffer before read count is incremented
|
||||
/* barrier insures data has been read out of buffer before read count is incremented */
|
||||
smp_mb();
|
||||
if ((int)(async->buf_read_count + nbytes -
|
||||
async->buf_read_alloc_count) > 0) {
|
||||
|
@ -680,7 +677,7 @@ unsigned comedi_buf_read_free(comedi_async * async, unsigned int nbytes)
|
|||
return nbytes;
|
||||
}
|
||||
|
||||
void comedi_buf_memcpy_to(comedi_async * async, unsigned int offset,
|
||||
void comedi_buf_memcpy_to(struct comedi_async *async, unsigned int offset,
|
||||
const void *data, unsigned int num_bytes)
|
||||
{
|
||||
unsigned int write_ptr = async->buf_write_ptr + offset;
|
||||
|
@ -705,7 +702,7 @@ void comedi_buf_memcpy_to(comedi_async * async, unsigned int offset,
|
|||
}
|
||||
}
|
||||
|
||||
void comedi_buf_memcpy_from(comedi_async * async, unsigned int offset,
|
||||
void comedi_buf_memcpy_from(struct comedi_async *async, unsigned int offset,
|
||||
void *dest, unsigned int nbytes)
|
||||
{
|
||||
void *src;
|
||||
|
@ -731,7 +728,7 @@ void comedi_buf_memcpy_from(comedi_async * async, unsigned int offset,
|
|||
}
|
||||
}
|
||||
|
||||
unsigned int comedi_buf_read_n_available(comedi_async * async)
|
||||
unsigned int comedi_buf_read_n_available(struct comedi_async *async)
|
||||
{
|
||||
unsigned num_bytes;
|
||||
|
||||
|
@ -746,32 +743,32 @@ unsigned int comedi_buf_read_n_available(comedi_async * async)
|
|||
return num_bytes;
|
||||
}
|
||||
|
||||
int comedi_buf_get(comedi_async * async, sampl_t * x)
|
||||
int comedi_buf_get(struct comedi_async *async, short *x)
|
||||
{
|
||||
unsigned int n = comedi_buf_read_n_available(async);
|
||||
|
||||
if (n < sizeof(sampl_t))
|
||||
if (n < sizeof(short))
|
||||
return 0;
|
||||
comedi_buf_read_alloc(async, sizeof(sampl_t));
|
||||
*x = *(sampl_t *) (async->prealloc_buf + async->buf_read_ptr);
|
||||
comedi_buf_read_free(async, sizeof(sampl_t));
|
||||
comedi_buf_read_alloc(async, sizeof(short));
|
||||
*x = *(short *) (async->prealloc_buf + async->buf_read_ptr);
|
||||
comedi_buf_read_free(async, sizeof(short));
|
||||
return 1;
|
||||
}
|
||||
|
||||
int comedi_buf_put(comedi_async * async, sampl_t x)
|
||||
int comedi_buf_put(struct comedi_async *async, short x)
|
||||
{
|
||||
unsigned int n = comedi_buf_write_alloc_strict(async, sizeof(sampl_t));
|
||||
unsigned int n = comedi_buf_write_alloc_strict(async, sizeof(short));
|
||||
|
||||
if (n < sizeof(sampl_t)) {
|
||||
if (n < sizeof(short)) {
|
||||
async->events |= COMEDI_CB_ERROR;
|
||||
return 0;
|
||||
}
|
||||
*(sampl_t *) (async->prealloc_buf + async->buf_write_ptr) = x;
|
||||
comedi_buf_write_free(async, sizeof(sampl_t));
|
||||
*(short *) (async->prealloc_buf + async->buf_write_ptr) = x;
|
||||
comedi_buf_write_free(async, sizeof(short));
|
||||
return 1;
|
||||
}
|
||||
|
||||
void comedi_reset_async_buf(comedi_async * async)
|
||||
void comedi_reset_async_buf(struct comedi_async *async)
|
||||
{
|
||||
async->buf_write_alloc_count = 0;
|
||||
async->buf_write_count = 0;
|
||||
|
@ -792,14 +789,27 @@ void comedi_reset_async_buf(comedi_async * async)
|
|||
|
||||
int comedi_auto_config(struct device *hardware_device, const char *board_name, const int *options, unsigned num_options)
|
||||
{
|
||||
comedi_devconfig it;
|
||||
struct comedi_devconfig it;
|
||||
int minor;
|
||||
struct comedi_device_file_info *dev_file_info;
|
||||
int retval;
|
||||
unsigned *private_data = NULL;
|
||||
|
||||
if (!comedi_autoconfig) {
|
||||
dev_set_drvdata(hardware_device, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
minor = comedi_alloc_board_minor(hardware_device);
|
||||
if(minor < 0) return minor;
|
||||
dev_set_drvdata(hardware_device, (void*)(unsigned long)minor);
|
||||
|
||||
private_data = kmalloc(sizeof(unsigned), GFP_KERNEL);
|
||||
if (private_data == NULL) {
|
||||
retval = -ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
*private_data = minor;
|
||||
dev_set_drvdata(hardware_device, private_data);
|
||||
|
||||
dev_file_info = comedi_get_device_file_info(minor);
|
||||
|
||||
|
@ -812,8 +822,11 @@ int comedi_auto_config(struct device *hardware_device, const char *board_name, c
|
|||
mutex_lock(&dev_file_info->device->mutex);
|
||||
retval = comedi_device_attach(dev_file_info->device, &it);
|
||||
mutex_unlock(&dev_file_info->device->mutex);
|
||||
|
||||
cleanup:
|
||||
if(retval < 0)
|
||||
{
|
||||
kfree(private_data);
|
||||
comedi_free_board_minor(minor);
|
||||
}
|
||||
return retval;
|
||||
|
@ -821,20 +834,23 @@ int comedi_auto_config(struct device *hardware_device, const char *board_name, c
|
|||
|
||||
void comedi_auto_unconfig(struct device *hardware_device)
|
||||
{
|
||||
unsigned long minor = (unsigned long)dev_get_drvdata(hardware_device);
|
||||
unsigned *minor = (unsigned *)dev_get_drvdata(hardware_device);
|
||||
if(minor == NULL) return;
|
||||
|
||||
BUG_ON(minor >= COMEDI_NUM_BOARD_MINORS);
|
||||
BUG_ON(*minor >= COMEDI_NUM_BOARD_MINORS);
|
||||
|
||||
comedi_free_board_minor(minor);
|
||||
comedi_free_board_minor(*minor);
|
||||
dev_set_drvdata(hardware_device, NULL);
|
||||
kfree(minor);
|
||||
}
|
||||
|
||||
int comedi_pci_auto_config(struct pci_dev *pcidev, const char *board_name)
|
||||
{
|
||||
int options[2];
|
||||
|
||||
// pci bus
|
||||
/* pci bus */
|
||||
options[0] = pcidev->bus->number;
|
||||
// pci slot
|
||||
/* pci slot */
|
||||
options[1] = PCI_SLOT(pcidev->devfn);
|
||||
|
||||
return comedi_auto_config(&pcidev->dev, board_name, options, sizeof(options) / sizeof(options[0]));
|
||||
|
@ -844,3 +860,16 @@ void comedi_pci_auto_unconfig(struct pci_dev *pcidev)
|
|||
{
|
||||
comedi_auto_unconfig(&pcidev->dev);
|
||||
}
|
||||
|
||||
int comedi_usb_auto_config(struct usb_device *usbdev,
|
||||
const char *board_name)
|
||||
{
|
||||
BUG_ON(usbdev == NULL);
|
||||
return comedi_auto_config(&usbdev->dev, board_name, NULL, 0);
|
||||
}
|
||||
|
||||
void comedi_usb_auto_unconfig(struct usb_device *usbdev)
|
||||
{
|
||||
BUG_ON(usbdev == NULL);
|
||||
comedi_auto_unconfig(&usbdev->dev);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,420 @@
|
|||
/*
|
||||
comedi/drivers/8253.h
|
||||
Header file for 8253
|
||||
|
||||
COMEDI - Linux Control and Measurement Device Interface
|
||||
Copyright (C) 2000 David A. Schleef <ds@schleef.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _8253_H
|
||||
#define _8253_H
|
||||
|
||||
#ifndef CMDTEST
|
||||
#include "../comedi.h"
|
||||
#else
|
||||
#include "../comedi.h"
|
||||
#endif
|
||||
|
||||
#define i8253_cascade_ns_to_timer i8253_cascade_ns_to_timer_2div
|
||||
|
||||
static inline void i8253_cascade_ns_to_timer_2div_old(int i8253_osc_base,
|
||||
unsigned int *d1, unsigned int *d2, unsigned int *nanosec,
|
||||
int round_mode)
|
||||
{
|
||||
int divider;
|
||||
int div1, div2;
|
||||
int div1_glb, div2_glb, ns_glb;
|
||||
int div1_lub, div2_lub, ns_lub;
|
||||
int ns;
|
||||
|
||||
divider = (*nanosec + i8253_osc_base / 2) / i8253_osc_base;
|
||||
|
||||
/* find 2 integers 1<={x,y}<=65536 such that x*y is
|
||||
close to divider */
|
||||
|
||||
div1_lub = div2_lub = 0;
|
||||
div1_glb = div2_glb = 0;
|
||||
|
||||
ns_glb = 0;
|
||||
ns_lub = 0xffffffff;
|
||||
|
||||
div2 = 0x10000;
|
||||
for (div1 = divider / 65536 + 1; div1 < div2; div1++) {
|
||||
div2 = divider / div1;
|
||||
|
||||
ns = i8253_osc_base * div1 * div2;
|
||||
if (ns <= *nanosec && ns > ns_glb) {
|
||||
ns_glb = ns;
|
||||
div1_glb = div1;
|
||||
div2_glb = div2;
|
||||
}
|
||||
|
||||
div2++;
|
||||
if (div2 <= 65536) {
|
||||
ns = i8253_osc_base * div1 * div2;
|
||||
if (ns > *nanosec && ns < ns_lub) {
|
||||
ns_lub = ns;
|
||||
div1_lub = div1;
|
||||
div2_lub = div2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*nanosec = div1_lub * div2_lub * i8253_osc_base;
|
||||
*d1 = div1_lub & 0xffff;
|
||||
*d2 = div2_lub & 0xffff;
|
||||
return;
|
||||
}
|
||||
|
||||
static inline void i8253_cascade_ns_to_timer_power(int i8253_osc_base,
|
||||
unsigned int *d1, unsigned int *d2, unsigned int *nanosec,
|
||||
int round_mode)
|
||||
{
|
||||
int div1, div2;
|
||||
int base;
|
||||
|
||||
for (div1 = 2; div1 <= (1 << 16); div1 <<= 1) {
|
||||
base = i8253_osc_base * div1;
|
||||
round_mode &= TRIG_ROUND_MASK;
|
||||
switch (round_mode) {
|
||||
case TRIG_ROUND_NEAREST:
|
||||
default:
|
||||
div2 = (*nanosec + base / 2) / base;
|
||||
break;
|
||||
case TRIG_ROUND_DOWN:
|
||||
div2 = (*nanosec) / base;
|
||||
break;
|
||||
case TRIG_ROUND_UP:
|
||||
div2 = (*nanosec + base - 1) / base;
|
||||
break;
|
||||
}
|
||||
if (div2 < 2)
|
||||
div2 = 2;
|
||||
if (div2 <= 65536) {
|
||||
*nanosec = div2 * base;
|
||||
*d1 = div1 & 0xffff;
|
||||
*d2 = div2 & 0xffff;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* shouldn't get here */
|
||||
div1 = 0x10000;
|
||||
div2 = 0x10000;
|
||||
*nanosec = div1 * div2 * i8253_osc_base;
|
||||
*d1 = div1 & 0xffff;
|
||||
*d2 = div2 & 0xffff;
|
||||
}
|
||||
|
||||
static inline void i8253_cascade_ns_to_timer_2div(int i8253_osc_base,
|
||||
unsigned int *d1, unsigned int *d2, unsigned int *nanosec,
|
||||
int round_mode)
|
||||
{
|
||||
unsigned int divider;
|
||||
unsigned int div1, div2;
|
||||
unsigned int div1_glb, div2_glb, ns_glb;
|
||||
unsigned int div1_lub, div2_lub, ns_lub;
|
||||
unsigned int ns;
|
||||
unsigned int start;
|
||||
unsigned int ns_low, ns_high;
|
||||
static const unsigned int max_count = 0x10000;
|
||||
/* exit early if everything is already correct (this can save time
|
||||
* since this function may be called repeatedly during command tests
|
||||
* and execution) */
|
||||
div1 = *d1 ? *d1 : max_count;
|
||||
div2 = *d2 ? *d2 : max_count;
|
||||
divider = div1 * div2;
|
||||
if (div1 * div2 * i8253_osc_base == *nanosec &&
|
||||
div1 > 1 && div1 <= max_count &&
|
||||
div2 > 1 && div2 <= max_count &&
|
||||
/* check for overflow */
|
||||
divider > div1 && divider > div2 &&
|
||||
divider * i8253_osc_base > divider &&
|
||||
divider * i8253_osc_base > i8253_osc_base) {
|
||||
return;
|
||||
}
|
||||
|
||||
divider = *nanosec / i8253_osc_base;
|
||||
|
||||
div1_lub = div2_lub = 0;
|
||||
div1_glb = div2_glb = 0;
|
||||
|
||||
ns_glb = 0;
|
||||
ns_lub = 0xffffffff;
|
||||
|
||||
div2 = max_count;
|
||||
start = divider / div2;
|
||||
if (start < 2)
|
||||
start = 2;
|
||||
for (div1 = start; div1 <= divider / div1 + 1 && div1 <= max_count;
|
||||
div1++) {
|
||||
for (div2 = divider / div1;
|
||||
div1 * div2 <= divider + div1 + 1 && div2 <= max_count;
|
||||
div2++) {
|
||||
ns = i8253_osc_base * div1 * div2;
|
||||
if (ns <= *nanosec && ns > ns_glb) {
|
||||
ns_glb = ns;
|
||||
div1_glb = div1;
|
||||
div2_glb = div2;
|
||||
}
|
||||
if (ns >= *nanosec && ns < ns_lub) {
|
||||
ns_lub = ns;
|
||||
div1_lub = div1;
|
||||
div2_lub = div2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
round_mode &= TRIG_ROUND_MASK;
|
||||
switch (round_mode) {
|
||||
case TRIG_ROUND_NEAREST:
|
||||
default:
|
||||
ns_high = div1_lub * div2_lub * i8253_osc_base;
|
||||
ns_low = div1_glb * div2_glb * i8253_osc_base;
|
||||
if (ns_high - *nanosec < *nanosec - ns_low) {
|
||||
div1 = div1_lub;
|
||||
div2 = div2_lub;
|
||||
} else {
|
||||
div1 = div1_glb;
|
||||
div2 = div2_glb;
|
||||
}
|
||||
break;
|
||||
case TRIG_ROUND_UP:
|
||||
div1 = div1_lub;
|
||||
div2 = div2_lub;
|
||||
break;
|
||||
case TRIG_ROUND_DOWN:
|
||||
div1 = div1_glb;
|
||||
div2 = div2_glb;
|
||||
break;
|
||||
}
|
||||
|
||||
*nanosec = div1 * div2 * i8253_osc_base;
|
||||
*d1 = div1 & 0xffff; // masking is done since counter maps zero to 0x10000
|
||||
*d2 = div2 & 0xffff;
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef CMDTEST
|
||||
/* i8254_load programs 8254 counter chip. It should also work for the 8253.
|
||||
* base_address is the lowest io address for the chip (the address of counter 0).
|
||||
* counter_number is the counter you want to load (0,1 or 2)
|
||||
* count is the number to load into the counter.
|
||||
*
|
||||
* You probably want to use mode 2.
|
||||
*
|
||||
* Use i8254_mm_load() if you board uses memory-mapped io, it is
|
||||
* the same as i8254_load() except it uses writeb() instead of outb().
|
||||
*
|
||||
* Neither i8254_load() or i8254_read() do their loading/reading
|
||||
* atomically. The 16 bit read/writes are performed with two successive
|
||||
* 8 bit read/writes. So if two parts of your driver do a load/read on
|
||||
* the same counter, it may be necessary to protect these functions
|
||||
* with a spinlock.
|
||||
*
|
||||
* FMH
|
||||
*/
|
||||
|
||||
#define i8254_control_reg 3
|
||||
|
||||
static inline int i8254_load(unsigned long base_address, unsigned int regshift,
|
||||
unsigned int counter_number, unsigned int count, unsigned int mode)
|
||||
{
|
||||
unsigned int byte;
|
||||
|
||||
if (counter_number > 2)
|
||||
return -1;
|
||||
if (count > 0xffff)
|
||||
return -1;
|
||||
if (mode > 5)
|
||||
return -1;
|
||||
if ((mode == 2 || mode == 3) && count == 1)
|
||||
return -1;
|
||||
|
||||
byte = counter_number << 6;
|
||||
byte |= 0x30; // load low then high byte
|
||||
byte |= (mode << 1); // set counter mode
|
||||
outb(byte, base_address + (i8254_control_reg << regshift));
|
||||
byte = count & 0xff; // lsb of counter value
|
||||
outb(byte, base_address + (counter_number << regshift));
|
||||
byte = (count >> 8) & 0xff; // msb of counter value
|
||||
outb(byte, base_address + (counter_number << regshift));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int i8254_mm_load(void *base_address, unsigned int regshift,
|
||||
unsigned int counter_number, unsigned int count, unsigned int mode)
|
||||
{
|
||||
unsigned int byte;
|
||||
|
||||
if (counter_number > 2)
|
||||
return -1;
|
||||
if (count > 0xffff)
|
||||
return -1;
|
||||
if (mode > 5)
|
||||
return -1;
|
||||
if ((mode == 2 || mode == 3) && count == 1)
|
||||
return -1;
|
||||
|
||||
byte = counter_number << 6;
|
||||
byte |= 0x30; // load low then high byte
|
||||
byte |= (mode << 1); // set counter mode
|
||||
writeb(byte, base_address + (i8254_control_reg << regshift));
|
||||
byte = count & 0xff; // lsb of counter value
|
||||
writeb(byte, base_address + (counter_number << regshift));
|
||||
byte = (count >> 8) & 0xff; // msb of counter value
|
||||
writeb(byte, base_address + (counter_number << regshift));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Returns 16 bit counter value, should work for 8253 also.*/
|
||||
static inline int i8254_read(unsigned long base_address, unsigned int regshift,
|
||||
unsigned int counter_number)
|
||||
{
|
||||
unsigned int byte;
|
||||
int ret;
|
||||
|
||||
if (counter_number > 2)
|
||||
return -1;
|
||||
|
||||
// latch counter
|
||||
byte = counter_number << 6;
|
||||
outb(byte, base_address + (i8254_control_reg << regshift));
|
||||
|
||||
// read lsb
|
||||
ret = inb(base_address + (counter_number << regshift));
|
||||
// read msb
|
||||
ret += inb(base_address + (counter_number << regshift)) << 8;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int i8254_mm_read(void *base_address, unsigned int regshift,
|
||||
unsigned int counter_number)
|
||||
{
|
||||
unsigned int byte;
|
||||
int ret;
|
||||
|
||||
if (counter_number > 2)
|
||||
return -1;
|
||||
|
||||
// latch counter
|
||||
byte = counter_number << 6;
|
||||
writeb(byte, base_address + (i8254_control_reg << regshift));
|
||||
|
||||
// read lsb
|
||||
ret = readb(base_address + (counter_number << regshift));
|
||||
// read msb
|
||||
ret += readb(base_address + (counter_number << regshift)) << 8;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Loads 16 bit initial counter value, should work for 8253 also. */
|
||||
static inline void i8254_write(unsigned long base_address,
|
||||
unsigned int regshift, unsigned int counter_number, unsigned int count)
|
||||
{
|
||||
unsigned int byte;
|
||||
|
||||
if (counter_number > 2)
|
||||
return;
|
||||
|
||||
byte = count & 0xff; // lsb of counter value
|
||||
outb(byte, base_address + (counter_number << regshift));
|
||||
byte = (count >> 8) & 0xff; // msb of counter value
|
||||
outb(byte, base_address + (counter_number << regshift));
|
||||
}
|
||||
|
||||
static inline void i8254_mm_write(void *base_address,
|
||||
unsigned int regshift, unsigned int counter_number, unsigned int count)
|
||||
{
|
||||
unsigned int byte;
|
||||
|
||||
if (counter_number > 2)
|
||||
return;
|
||||
|
||||
byte = count & 0xff; // lsb of counter value
|
||||
writeb(byte, base_address + (counter_number << regshift));
|
||||
byte = (count >> 8) & 0xff; // msb of counter value
|
||||
writeb(byte, base_address + (counter_number << regshift));
|
||||
}
|
||||
|
||||
/* Set counter mode, should work for 8253 also.
|
||||
* Note: the 'mode' value is different to that for i8254_load() and comes
|
||||
* from the INSN_CONFIG_8254_SET_MODE command:
|
||||
* I8254_MODE0, I8254_MODE1, ..., I8254_MODE5
|
||||
* OR'ed with:
|
||||
* I8254_BCD, I8254_BINARY
|
||||
*/
|
||||
static inline int i8254_set_mode(unsigned long base_address,
|
||||
unsigned int regshift, unsigned int counter_number, unsigned int mode)
|
||||
{
|
||||
unsigned int byte;
|
||||
|
||||
if (counter_number > 2)
|
||||
return -1;
|
||||
if (mode > (I8254_MODE5 | I8254_BINARY))
|
||||
return -1;
|
||||
|
||||
byte = counter_number << 6;
|
||||
byte |= 0x30; // load low then high byte
|
||||
byte |= mode; // set counter mode and BCD|binary
|
||||
outb(byte, base_address + (i8254_control_reg << regshift));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int i8254_mm_set_mode(void *base_address,
|
||||
unsigned int regshift, unsigned int counter_number, unsigned int mode)
|
||||
{
|
||||
unsigned int byte;
|
||||
|
||||
if (counter_number > 2)
|
||||
return -1;
|
||||
if (mode > (I8254_MODE5 | I8254_BINARY))
|
||||
return -1;
|
||||
|
||||
byte = counter_number << 6;
|
||||
byte |= 0x30; // load low then high byte
|
||||
byte |= mode; // set counter mode and BCD|binary
|
||||
writeb(byte, base_address + (i8254_control_reg << regshift));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int i8254_status(unsigned long base_address,
|
||||
unsigned int regshift, unsigned int counter_number)
|
||||
{
|
||||
outb(0xE0 | (2 << counter_number),
|
||||
base_address + (i8254_control_reg << regshift));
|
||||
return inb(base_address + (counter_number << regshift));
|
||||
}
|
||||
|
||||
static inline int i8254_mm_status(void *base_address,
|
||||
unsigned int regshift, unsigned int counter_number)
|
||||
{
|
||||
writeb(0xE0 | (2 << counter_number),
|
||||
base_address + (i8254_control_reg << regshift));
|
||||
return readb(base_address + (counter_number << regshift));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,442 @@
|
|||
/*
|
||||
comedi/drivers/8255.c
|
||||
Driver for 8255
|
||||
|
||||
COMEDI - Linux Control and Measurement Device Interface
|
||||
Copyright (C) 1998 David A. Schleef <ds@schleef.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
/*
|
||||
Driver: 8255
|
||||
Description: generic 8255 support
|
||||
Devices: [standard] 8255 (8255)
|
||||
Author: ds
|
||||
Status: works
|
||||
Updated: Fri, 7 Jun 2002 12:56:45 -0700
|
||||
|
||||
The classic in digital I/O. The 8255 appears in Comedi as a single
|
||||
digital I/O subdevice with 24 channels. The channel 0 corresponds
|
||||
to the 8255's port A, bit 0; channel 23 corresponds to port C, bit
|
||||
7. Direction configuration is done in blocks, with channels 0-7,
|
||||
8-15, 16-19, and 20-23 making up the 4 blocks. The only 8255 mode
|
||||
supported is mode 0.
|
||||
|
||||
You should enable compilation this driver if you plan to use a board
|
||||
that has an 8255 chip. For multifunction boards, the main driver will
|
||||
configure the 8255 subdevice automatically.
|
||||
|
||||
This driver also works independently with ISA and PCI cards that
|
||||
directly map the 8255 registers to I/O ports, including cards with
|
||||
multiple 8255 chips. To configure the driver for such a card, the
|
||||
option list should be a list of the I/O port bases for each of the
|
||||
8255 chips. For example,
|
||||
|
||||
comedi_config /dev/comedi0 8255 0x200,0x204,0x208,0x20c
|
||||
|
||||
Note that most PCI 8255 boards do NOT work with this driver, and
|
||||
need a separate driver as a wrapper. For those that do work, the
|
||||
I/O port base address can be found in the output of 'lspci -v'.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
This file contains an exported subdevice for driving an 8255.
|
||||
|
||||
To use this subdevice as part of another driver, you need to
|
||||
set up the subdevice in the attach function of the driver by
|
||||
calling:
|
||||
|
||||
subdev_8255_init(device, subdevice, callback_function, arg)
|
||||
|
||||
device and subdevice are pointers to the device and subdevice
|
||||
structures. callback_function will be called to provide the
|
||||
low-level input/output to the device, i.e., actual register
|
||||
access. callback_function will be called with the value of arg
|
||||
as the last parameter. If the 8255 device is mapped as 4
|
||||
consecutive I/O ports, you can use NULL for callback_function
|
||||
and the I/O port base for arg, and an internal function will
|
||||
handle the register access.
|
||||
|
||||
In addition, if the main driver handles interrupts, you can
|
||||
enable commands on the subdevice by calling subdev_8255_init_irq()
|
||||
instead. Then, when you get an interrupt that is likely to be
|
||||
from the 8255, you should call subdev_8255_interrupt(), which
|
||||
will copy the latched value to a Comedi buffer.
|
||||
*/
|
||||
|
||||
#include "../comedidev.h"
|
||||
|
||||
#include <linux/ioport.h>
|
||||
|
||||
#define _8255_SIZE 4
|
||||
|
||||
#define _8255_DATA 0
|
||||
#define _8255_CR 3
|
||||
|
||||
#define CR_C_LO_IO 0x01
|
||||
#define CR_B_IO 0x02
|
||||
#define CR_B_MODE 0x04
|
||||
#define CR_C_HI_IO 0x08
|
||||
#define CR_A_IO 0x10
|
||||
#define CR_A_MODE(a) ((a)<<5)
|
||||
#define CR_CW 0x80
|
||||
|
||||
struct subdev_8255_struct {
|
||||
unsigned long cb_arg;
|
||||
int (*cb_func) (int, int, int, unsigned long);
|
||||
int have_irq;
|
||||
};
|
||||
|
||||
#define CALLBACK_ARG (((struct subdev_8255_struct *)s->private)->cb_arg)
|
||||
#define CALLBACK_FUNC (((struct subdev_8255_struct *)s->private)->cb_func)
|
||||
#define subdevpriv ((struct subdev_8255_struct *)s->private)
|
||||
|
||||
static int dev_8255_attach(struct comedi_device *dev, struct comedi_devconfig * it);
|
||||
static int dev_8255_detach(struct comedi_device *dev);
|
||||
static struct comedi_driver driver_8255 = {
|
||||
driver_name:"8255",
|
||||
module:THIS_MODULE,
|
||||
attach:dev_8255_attach,
|
||||
detach:dev_8255_detach,
|
||||
};
|
||||
|
||||
COMEDI_INITCLEANUP(driver_8255);
|
||||
|
||||
static void do_config(struct comedi_device *dev, struct comedi_subdevice * s);
|
||||
|
||||
void subdev_8255_interrupt(struct comedi_device *dev, struct comedi_subdevice * s)
|
||||
{
|
||||
short d;
|
||||
|
||||
d = CALLBACK_FUNC(0, _8255_DATA, 0, CALLBACK_ARG);
|
||||
d |= (CALLBACK_FUNC(0, _8255_DATA + 1, 0, CALLBACK_ARG) << 8);
|
||||
|
||||
comedi_buf_put(s->async, d);
|
||||
s->async->events |= COMEDI_CB_EOS;
|
||||
|
||||
comedi_event(dev, s);
|
||||
}
|
||||
|
||||
static int subdev_8255_cb(int dir, int port, int data, unsigned long arg)
|
||||
{
|
||||
unsigned long iobase = arg;
|
||||
|
||||
if (dir) {
|
||||
outb(data, iobase + port);
|
||||
return 0;
|
||||
} else {
|
||||
return inb(iobase + port);
|
||||
}
|
||||
}
|
||||
|
||||
static int subdev_8255_insn(struct comedi_device *dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
if (data[0]) {
|
||||
s->state &= ~data[0];
|
||||
s->state |= (data[0] & data[1]);
|
||||
|
||||
if (data[0] & 0xff)
|
||||
CALLBACK_FUNC(1, _8255_DATA, s->state & 0xff,
|
||||
CALLBACK_ARG);
|
||||
if (data[0] & 0xff00)
|
||||
CALLBACK_FUNC(1, _8255_DATA + 1, (s->state >> 8) & 0xff,
|
||||
CALLBACK_ARG);
|
||||
if (data[0] & 0xff0000)
|
||||
CALLBACK_FUNC(1, _8255_DATA + 2,
|
||||
(s->state >> 16) & 0xff, CALLBACK_ARG);
|
||||
}
|
||||
|
||||
data[1] = CALLBACK_FUNC(0, _8255_DATA, 0, CALLBACK_ARG);
|
||||
data[1] |= (CALLBACK_FUNC(0, _8255_DATA + 1, 0, CALLBACK_ARG) << 8);
|
||||
data[1] |= (CALLBACK_FUNC(0, _8255_DATA + 2, 0, CALLBACK_ARG) << 16);
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int subdev_8255_insn_config(struct comedi_device *dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
unsigned int mask;
|
||||
unsigned int bits;
|
||||
|
||||
mask = 1 << CR_CHAN(insn->chanspec);
|
||||
if (mask & 0x0000ff) {
|
||||
bits = 0x0000ff;
|
||||
} else if (mask & 0x00ff00) {
|
||||
bits = 0x00ff00;
|
||||
} else if (mask & 0x0f0000) {
|
||||
bits = 0x0f0000;
|
||||
} else {
|
||||
bits = 0xf00000;
|
||||
}
|
||||
|
||||
switch (data[0]) {
|
||||
case INSN_CONFIG_DIO_INPUT:
|
||||
s->io_bits &= ~bits;
|
||||
break;
|
||||
case INSN_CONFIG_DIO_OUTPUT:
|
||||
s->io_bits |= bits;
|
||||
break;
|
||||
case INSN_CONFIG_DIO_QUERY:
|
||||
data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
|
||||
return insn->n;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
do_config(dev, s);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void do_config(struct comedi_device *dev, struct comedi_subdevice * s)
|
||||
{
|
||||
int config;
|
||||
|
||||
config = CR_CW;
|
||||
/* 1 in io_bits indicates output, 1 in config indicates input */
|
||||
if (!(s->io_bits & 0x0000ff))
|
||||
config |= CR_A_IO;
|
||||
if (!(s->io_bits & 0x00ff00))
|
||||
config |= CR_B_IO;
|
||||
if (!(s->io_bits & 0x0f0000))
|
||||
config |= CR_C_LO_IO;
|
||||
if (!(s->io_bits & 0xf00000))
|
||||
config |= CR_C_HI_IO;
|
||||
CALLBACK_FUNC(1, _8255_CR, config, CALLBACK_ARG);
|
||||
}
|
||||
|
||||
static int subdev_8255_cmdtest(struct comedi_device *dev, struct comedi_subdevice * s,
|
||||
struct comedi_cmd * cmd)
|
||||
{
|
||||
int err = 0;
|
||||
unsigned int tmp;
|
||||
|
||||
/* step 1 */
|
||||
|
||||
tmp = cmd->start_src;
|
||||
cmd->start_src &= TRIG_NOW;
|
||||
if (!cmd->start_src || tmp != cmd->start_src)
|
||||
err++;
|
||||
|
||||
tmp = cmd->scan_begin_src;
|
||||
cmd->scan_begin_src &= TRIG_EXT;
|
||||
if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
|
||||
err++;
|
||||
|
||||
tmp = cmd->convert_src;
|
||||
cmd->convert_src &= TRIG_FOLLOW;
|
||||
if (!cmd->convert_src || tmp != cmd->convert_src)
|
||||
err++;
|
||||
|
||||
tmp = cmd->scan_end_src;
|
||||
cmd->scan_end_src &= TRIG_COUNT;
|
||||
if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
|
||||
err++;
|
||||
|
||||
tmp = cmd->stop_src;
|
||||
cmd->stop_src &= TRIG_NONE;
|
||||
if (!cmd->stop_src || tmp != cmd->stop_src)
|
||||
err++;
|
||||
|
||||
if (err)
|
||||
return 1;
|
||||
|
||||
/* step 2 */
|
||||
|
||||
if (err)
|
||||
return 2;
|
||||
|
||||
/* step 3 */
|
||||
|
||||
if (cmd->start_arg != 0) {
|
||||
cmd->start_arg = 0;
|
||||
err++;
|
||||
}
|
||||
if (cmd->scan_begin_arg != 0) {
|
||||
cmd->scan_begin_arg = 0;
|
||||
err++;
|
||||
}
|
||||
if (cmd->convert_arg != 0) {
|
||||
cmd->convert_arg = 0;
|
||||
err++;
|
||||
}
|
||||
if (cmd->scan_end_arg != 1) {
|
||||
cmd->scan_end_arg = 1;
|
||||
err++;
|
||||
}
|
||||
if (cmd->stop_arg != 0) {
|
||||
cmd->stop_arg = 0;
|
||||
err++;
|
||||
}
|
||||
|
||||
if (err)
|
||||
return 3;
|
||||
|
||||
/* step 4 */
|
||||
|
||||
if (err)
|
||||
return 4;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int subdev_8255_cmd(struct comedi_device *dev, struct comedi_subdevice * s)
|
||||
{
|
||||
/* FIXME */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int subdev_8255_cancel(struct comedi_device *dev, struct comedi_subdevice * s)
|
||||
{
|
||||
/* FIXME */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice * s, int (*cb) (int,
|
||||
int, int, unsigned long), unsigned long arg)
|
||||
{
|
||||
s->type = COMEDI_SUBD_DIO;
|
||||
s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
|
||||
s->n_chan = 24;
|
||||
s->range_table = &range_digital;
|
||||
s->maxdata = 1;
|
||||
|
||||
s->private = kmalloc(sizeof(struct subdev_8255_struct), GFP_KERNEL);
|
||||
if (!s->private)
|
||||
return -ENOMEM;
|
||||
|
||||
CALLBACK_ARG = arg;
|
||||
if (cb == NULL) {
|
||||
CALLBACK_FUNC = subdev_8255_cb;
|
||||
} else {
|
||||
CALLBACK_FUNC = cb;
|
||||
}
|
||||
s->insn_bits = subdev_8255_insn;
|
||||
s->insn_config = subdev_8255_insn_config;
|
||||
|
||||
s->state = 0;
|
||||
s->io_bits = 0;
|
||||
do_config(dev, s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int subdev_8255_init_irq(struct comedi_device *dev, struct comedi_subdevice * s,
|
||||
int (*cb) (int, int, int, unsigned long), unsigned long arg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = subdev_8255_init(dev, s, cb, arg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
s->do_cmdtest = subdev_8255_cmdtest;
|
||||
s->do_cmd = subdev_8255_cmd;
|
||||
s->cancel = subdev_8255_cancel;
|
||||
|
||||
subdevpriv->have_irq = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void subdev_8255_cleanup(struct comedi_device *dev, struct comedi_subdevice * s)
|
||||
{
|
||||
if (s->private) {
|
||||
if (subdevpriv->have_irq) {
|
||||
}
|
||||
|
||||
kfree(s->private);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Start of the 8255 standalone device
|
||||
|
||||
*/
|
||||
|
||||
static int dev_8255_attach(struct comedi_device *dev, struct comedi_devconfig * it)
|
||||
{
|
||||
int ret;
|
||||
unsigned long iobase;
|
||||
int i;
|
||||
|
||||
printk("comedi%d: 8255:", dev->minor);
|
||||
|
||||
dev->board_name = "8255";
|
||||
|
||||
for (i = 0; i < COMEDI_NDEVCONFOPTS; i++) {
|
||||
iobase = it->options[i];
|
||||
if (!iobase)
|
||||
break;
|
||||
}
|
||||
if (i == 0) {
|
||||
printk(" no devices specified\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((ret = alloc_subdevices(dev, i)) < 0)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < dev->n_subdevices; i++) {
|
||||
iobase = it->options[i];
|
||||
|
||||
printk(" 0x%04lx", iobase);
|
||||
if (!request_region(iobase, _8255_SIZE, "8255")) {
|
||||
printk(" (I/O port conflict)");
|
||||
|
||||
dev->subdevices[i].type = COMEDI_SUBD_UNUSED;
|
||||
} else {
|
||||
subdev_8255_init(dev, dev->subdevices + i, NULL,
|
||||
iobase);
|
||||
}
|
||||
}
|
||||
|
||||
printk("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dev_8255_detach(struct comedi_device *dev)
|
||||
{
|
||||
int i;
|
||||
unsigned long iobase;
|
||||
struct comedi_subdevice *s;
|
||||
|
||||
printk("comedi%d: 8255: remove\n", dev->minor);
|
||||
|
||||
for (i = 0; i < dev->n_subdevices; i++) {
|
||||
s = dev->subdevices + i;
|
||||
if (s->type != COMEDI_SUBD_UNUSED) {
|
||||
iobase = CALLBACK_ARG;
|
||||
release_region(iobase, _8255_SIZE);
|
||||
}
|
||||
subdev_8255_cleanup(dev, s);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(subdev_8255_init);
|
||||
EXPORT_SYMBOL(subdev_8255_init_irq);
|
||||
EXPORT_SYMBOL(subdev_8255_cleanup);
|
||||
EXPORT_SYMBOL(subdev_8255_interrupt);
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
module/8255.h
|
||||
Header file for 8255
|
||||
|
||||
COMEDI - Linux Control and Measurement Device Interface
|
||||
Copyright (C) 1998 David A. Schleef <ds@schleef.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _8255_H
|
||||
#define _8255_H
|
||||
|
||||
#include "../comedidev.h"
|
||||
|
||||
#if defined(CONFIG_COMEDI_8255) || defined(CONFIG_COMEDI_8255_MODULE)
|
||||
|
||||
int subdev_8255_init(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
int (*cb) (int, int, int, unsigned long), unsigned long arg);
|
||||
int subdev_8255_init_irq(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
int (*cb) (int, int, int, unsigned long), unsigned long arg);
|
||||
void subdev_8255_cleanup(struct comedi_device * dev, struct comedi_subdevice * s);
|
||||
void subdev_8255_interrupt(struct comedi_device * dev, struct comedi_subdevice * s);
|
||||
|
||||
#else
|
||||
|
||||
static inline int subdev_8255_init(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
void *x, unsigned long y)
|
||||
{
|
||||
printk("8255 support not configured -- disabling subdevice\n");
|
||||
|
||||
s->type = COMEDI_SUBD_UNUSED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void subdev_8255_cleanup(struct comedi_device * dev,
|
||||
struct comedi_subdevice * s)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -8,12 +8,121 @@ obj-$(CONFIG_COMEDI) += comedi_test.o
|
|||
obj-$(CONFIG_COMEDI) += comedi_parport.o
|
||||
|
||||
# Comedi PCI drivers
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += mite.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += 8255.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += acl7225b.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_035.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_1032.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_1500.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_1516.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_1564.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_16xx.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_2016.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_2032.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_2200.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_3001.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_3120.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_3501.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_3xxx.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adl_pci6208.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adl_pci7296.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adl_pci7432.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adl_pci8164.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adl_pci9111.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adl_pci9118.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adq12b.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adv_pci1710.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adv_pci1723.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adv_pci_dio.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += aio_aio12_8.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += aio_iiro_16.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += amplc_dio200.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += amplc_pc236.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += amplc_pc263.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += amplc_pci224.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += amplc_pci230.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += c6xdigio.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += cb_pcidas64.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += cb_pcidas.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += cb_pcidda.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += cb_pcidio.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += cb_pcimdas.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += cb_pcimdda.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += comedi_bond.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += comedi_parport.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += comedi_test.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += contec_pci_dio.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += daqboard2000.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += das08.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += das16m1.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += das16.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += das1800.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += das6402.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += das800.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += dmm32at.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += dt2801.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += dt2811.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += dt2814.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += dt2815.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += dt2817.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += dt282x.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += dt3000.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += fl512.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += gsc_hpdi.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += icp_multi.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += me_daq.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ii_pci20kc.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += jr3_pci.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ke_counter.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += me4000.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += me_daq.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += mite.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += mpc624.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += multiq3.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_6527.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_65xx.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_660x.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_670x.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_at_a2150.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_at_ao.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_atmio16d.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_atmio.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_labpc.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_pcidio.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_pcimio.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_tiocmd.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_tio.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcl711.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcl724.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcl725.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcl726.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcl730.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcl812.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcl816.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcl818.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcm3724.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcm3730.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcmad.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcmda12.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcmmio.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcmuio.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += poc.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += rtd520.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += rti800.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += rti802.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += s526.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += s626.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += serial2002.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += skel.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ssv_dnp.o
|
||||
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += unioxx5.o
|
||||
|
||||
# Comedi PCMCIA drivers
|
||||
obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS) += cb_das16_cs.o
|
||||
obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS) += das08_cs.o
|
||||
obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS) += ni_daq_700.o
|
||||
obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS) += ni_daq_dio24.o
|
||||
obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS) += ni_labpc_cs.o
|
||||
obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS) += ni_mio_cs.o
|
||||
obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS) += quatech_daqp_cs.o
|
||||
|
||||
# Comedi USB drivers
|
||||
obj-$(CONFIG_COMEDI_USB_DRIVERS) += usbdux.o
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
* comedi/drivers/acl7225b.c
|
||||
* Driver for Adlink NuDAQ ACL-7225b and clones
|
||||
* José Luis Sánchez
|
||||
*/
|
||||
/*
|
||||
Driver: acl7225b
|
||||
Description: Adlink NuDAQ ACL-7225b & compatibles
|
||||
Author: José Luis Sánchez (jsanchezv@teleline.es)
|
||||
Status: testing
|
||||
Devices: [Adlink] ACL-7225b (acl7225b), [ICP] P16R16DIO (p16r16dio)
|
||||
*/
|
||||
|
||||
#include "../comedidev.h"
|
||||
|
||||
#include <linux/ioport.h>
|
||||
|
||||
#define ACL7225_SIZE 8 /* Requires 8 ioports, but only 4 are used */
|
||||
#define P16R16DIO_SIZE 4
|
||||
#define ACL7225_RIO_LO 0 /* Relays input/output low byte (R0-R7) */
|
||||
#define ACL7225_RIO_HI 1 /* Relays input/output high byte (R8-R15) */
|
||||
#define ACL7225_DI_LO 2 /* Digital input low byte (DI0-DI7) */
|
||||
#define ACL7225_DI_HI 3 /* Digital input high byte (DI8-DI15) */
|
||||
|
||||
static int acl7225b_attach(struct comedi_device *dev, struct comedi_devconfig * it);
|
||||
static int acl7225b_detach(struct comedi_device *dev);
|
||||
|
||||
struct boardtype {
|
||||
const char *name; // driver name
|
||||
int io_range; // len of I/O space
|
||||
};
|
||||
|
||||
static const struct boardtype boardtypes[] = {
|
||||
{"acl7225b", ACL7225_SIZE,},
|
||||
{"p16r16dio", P16R16DIO_SIZE,},
|
||||
};
|
||||
|
||||
#define n_boardtypes (sizeof(boardtypes)/sizeof(struct boardtype))
|
||||
#define this_board ((const struct boardtype *)dev->board_ptr)
|
||||
|
||||
static struct comedi_driver driver_acl7225b = {
|
||||
driver_name:"acl7225b",
|
||||
module:THIS_MODULE,
|
||||
attach:acl7225b_attach,
|
||||
detach:acl7225b_detach,
|
||||
board_name:&boardtypes[0].name,
|
||||
num_names:n_boardtypes,
|
||||
offset:sizeof(struct boardtype),
|
||||
};
|
||||
|
||||
COMEDI_INITCLEANUP(driver_acl7225b);
|
||||
|
||||
static int acl7225b_do_insn(struct comedi_device *dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
if (insn->n != 2)
|
||||
return -EINVAL;
|
||||
|
||||
if (data[0]) {
|
||||
s->state &= ~data[0];
|
||||
s->state |= (data[0] & data[1]);
|
||||
}
|
||||
if (data[0] & 0x00ff)
|
||||
outb(s->state & 0xff, dev->iobase + (unsigned long)s->private);
|
||||
if (data[0] & 0xff00)
|
||||
outb((s->state >> 8),
|
||||
dev->iobase + (unsigned long)s->private + 1);
|
||||
|
||||
data[1] = s->state;
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int acl7225b_di_insn(struct comedi_device *dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
if (insn->n != 2)
|
||||
return -EINVAL;
|
||||
|
||||
data[1] = inb(dev->iobase + (unsigned long)s->private) |
|
||||
(inb(dev->iobase + (unsigned long)s->private + 1) << 8);
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int acl7225b_attach(struct comedi_device *dev, struct comedi_devconfig * it)
|
||||
{
|
||||
struct comedi_subdevice *s;
|
||||
int iobase, iorange;
|
||||
|
||||
iobase = it->options[0];
|
||||
iorange = this_board->io_range;
|
||||
printk("comedi%d: acl7225b: board=%s 0x%04x ", dev->minor,
|
||||
this_board->name, iobase);
|
||||
if (!request_region(iobase, iorange, "acl7225b")) {
|
||||
printk("I/O port conflict\n");
|
||||
return -EIO;
|
||||
}
|
||||
dev->board_name = this_board->name;
|
||||
dev->iobase = iobase;
|
||||
dev->irq = 0;
|
||||
|
||||
if (alloc_subdevices(dev, 3) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
s = dev->subdevices + 0;
|
||||
/* Relays outputs */
|
||||
s->type = COMEDI_SUBD_DO;
|
||||
s->subdev_flags = SDF_WRITABLE;
|
||||
s->maxdata = 1;
|
||||
s->n_chan = 16;
|
||||
s->insn_bits = acl7225b_do_insn;
|
||||
s->range_table = &range_digital;
|
||||
s->private = (void *)ACL7225_RIO_LO;
|
||||
|
||||
s = dev->subdevices + 1;
|
||||
/* Relays status */
|
||||
s->type = COMEDI_SUBD_DI;
|
||||
s->subdev_flags = SDF_READABLE;
|
||||
s->maxdata = 1;
|
||||
s->n_chan = 16;
|
||||
s->insn_bits = acl7225b_di_insn;
|
||||
s->range_table = &range_digital;
|
||||
s->private = (void *)ACL7225_RIO_LO;
|
||||
|
||||
s = dev->subdevices + 2;
|
||||
/* Isolated digital inputs */
|
||||
s->type = COMEDI_SUBD_DI;
|
||||
s->subdev_flags = SDF_READABLE;
|
||||
s->maxdata = 1;
|
||||
s->n_chan = 16;
|
||||
s->insn_bits = acl7225b_di_insn;
|
||||
s->range_table = &range_digital;
|
||||
s->private = (void *)ACL7225_DI_LO;
|
||||
|
||||
printk("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acl7225b_detach(struct comedi_device *dev)
|
||||
{
|
||||
printk("comedi%d: acl7225b: remove\n", dev->minor);
|
||||
|
||||
if (dev->iobase)
|
||||
release_region(dev->iobase, this_board->io_range);
|
||||
|
||||
return 0;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
*
|
||||
* ADDI-DATA GmbH
|
||||
* Dieselstrasse 3
|
||||
* D-77833 Ottersweier
|
||||
* Tel: +19(0)7223/9493-0
|
||||
* Fax: +49(0)7223/9493-92
|
||||
* http://www.addi-data-com
|
||||
* info@addi-data.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*/
|
||||
|
||||
#define APCI1710_PCI_BUS_CLOCK 0
|
||||
#define APCI1710_FRONT_CONNECTOR_INPUT 1
|
||||
#define APCI1710_TIMER_READVALUE 0
|
||||
#define APCI1710_TIMER_GETOUTPUTLEVEL 1
|
||||
#define APCI1710_TIMER_GETPROGRESSSTATUS 2
|
||||
#define APCI1710_TIMER_WRITEVALUE 3
|
||||
|
||||
#define APCI1710_TIMER_READINTERRUPT 1
|
||||
#define APCI1710_TIMER_READALLTIMER 2
|
||||
|
||||
/* BEGIN JK 27.10.03 : Add the possibility to use a 40 Mhz quartz */
|
||||
#ifndef APCI1710_10MHZ
|
||||
#define APCI1710_10MHZ 10
|
||||
#endif
|
||||
/* END JK 27.10.03 : Add the possibility to use a 40 Mhz quartz */
|
||||
|
||||
/*
|
||||
* 82X54 TIMER INISIALISATION FUNCTION
|
||||
*/
|
||||
INT i_APCI1710_InsnConfigInitTimer(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
INT i_APCI1710_InsnWriteEnableDisableTimer(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
/*
|
||||
* 82X54 READ FUNCTION
|
||||
*/
|
||||
INT i_APCI1710_InsnReadAllTimerValue(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
INT i_APCI1710_InsnBitsTimer(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
/*
|
||||
* 82X54 READ & WRITE FUNCTION
|
||||
*/
|
||||
INT i_APCI1710_ReadTimerValue(struct comedi_device *dev,
|
||||
BYTE b_ModulNbr, BYTE b_TimerNbr,
|
||||
PULONG pul_TimerValue);
|
||||
|
||||
INT i_APCI1710_GetTimerOutputLevel(struct comedi_device *dev,
|
||||
BYTE b_ModulNbr, BYTE b_TimerNbr,
|
||||
PBYTE pb_OutputLevel);
|
||||
|
||||
INT i_APCI1710_GetTimerProgressStatus(struct comedi_device *dev,
|
||||
BYTE b_ModulNbr, BYTE b_TimerNbr,
|
||||
PBYTE pb_TimerStatus);
|
||||
|
||||
/*
|
||||
* 82X54 WRITE FUNCTION
|
||||
*/
|
||||
INT i_APCI1710_WriteTimerValue(struct comedi_device *dev,
|
||||
BYTE b_ModulNbr, BYTE b_TimerNbr,
|
||||
ULONG ul_WriteValue);
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
*
|
||||
* ADDI-DATA GmbH
|
||||
* Dieselstrasse 3
|
||||
* D-77833 Ottersweier
|
||||
* Tel: +19(0)7223/9493-0
|
||||
* Fax: +49(0)7223/9493-92
|
||||
* http://www.addi-data-com
|
||||
* info@addi-data.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*/
|
||||
|
||||
#define APCI1710_30MHZ 30
|
||||
#define APCI1710_33MHZ 33
|
||||
#define APCI1710_40MHZ 40
|
||||
|
||||
#define APCI1710_SINGLE 0
|
||||
#define APCI1710_CONTINUOUS 1
|
||||
|
||||
#define APCI1710_CHRONO_PROGRESS_STATUS 0
|
||||
#define APCI1710_CHRONO_READVALUE 1
|
||||
#define APCI1710_CHRONO_CONVERTVALUE 2
|
||||
#define APCI1710_CHRONO_READINTERRUPT 3
|
||||
|
||||
#define APCI1710_CHRONO_SET_CHANNELON 0
|
||||
#define APCI1710_CHRONO_SET_CHANNELOFF 1
|
||||
#define APCI1710_CHRONO_READ_CHANNEL 2
|
||||
#define APCI1710_CHRONO_READ_PORT 3
|
||||
|
||||
/*
|
||||
* CHRONOMETER INISIALISATION FUNCTION
|
||||
*/
|
||||
INT i_APCI1710_InsnConfigInitChrono(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
INT i_APCI1710_InsnWriteEnableDisableChrono(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
|
||||
/*
|
||||
* CHRONOMETER READ FUNCTION
|
||||
*/
|
||||
INT i_APCI1710_InsnReadChrono(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
INT i_APCI1710_GetChronoProgressStatus(struct comedi_device *dev,
|
||||
BYTE b_ModulNbr, PBYTE pb_ChronoStatus);
|
||||
|
||||
INT i_APCI1710_ReadChronoValue(struct comedi_device *dev,
|
||||
BYTE b_ModulNbr,
|
||||
UINT ui_TimeOut, PBYTE pb_ChronoStatus,
|
||||
PULONG pul_ChronoValue);
|
||||
|
||||
INT i_APCI1710_ConvertChronoValue(struct comedi_device *dev,
|
||||
BYTE b_ModulNbr,
|
||||
ULONG ul_ChronoValue,
|
||||
PULONG pul_Hour,
|
||||
PBYTE pb_Minute,
|
||||
PBYTE pb_Second,
|
||||
PUINT pui_MilliSecond, PUINT pui_MicroSecond,
|
||||
PUINT pui_NanoSecond);
|
||||
|
||||
/*
|
||||
* CHRONOMETER DIGITAL INPUT OUTPUT FUNCTION
|
||||
*/
|
||||
INT i_APCI1710_InsnBitsChronoDigitalIO(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn,
|
||||
unsigned int *data);
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
*
|
||||
* ADDI-DATA GmbH
|
||||
* Dieselstrasse 3
|
||||
* D-77833 Ottersweier
|
||||
* Tel: +19(0)7223/9493-0
|
||||
* Fax: +49(0)7223/9493-92
|
||||
* http://www.addi-data-com
|
||||
* info@addi-data.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*/
|
||||
|
||||
#define APCI1710_ON 1 /* Digital Output ON or OFF */
|
||||
#define APCI1710_OFF 0
|
||||
|
||||
#define APCI1710_INPUT 0 /* Digital I/O */
|
||||
#define APCI1710_OUTPUT 1
|
||||
|
||||
#define APCI1710_DIGIO_MEMORYONOFF 0x10
|
||||
#define APCI1710_DIGIO_INIT 0x11
|
||||
|
||||
/*
|
||||
* DIGITAL I/O INISIALISATION FUNCTION
|
||||
*/
|
||||
INT i_APCI1710_InsnConfigDigitalIO(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
/*
|
||||
* INPUT OUTPUT FUNCTIONS
|
||||
*/
|
||||
INT i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
INT i_APCI1710_InsnWriteDigitalIOChlOnOff(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
INT i_APCI1710_InsnBitsDigitalIOPortOnOff(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,271 @@
|
|||
/*
|
||||
* Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
*
|
||||
* ADDI-DATA GmbH
|
||||
* Dieselstrasse 3
|
||||
* D-77833 Ottersweier
|
||||
* Tel: +19(0)7223/9493-0
|
||||
* Fax: +49(0)7223/9493-92
|
||||
* http://www.addi-data-com
|
||||
* info@addi-data.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*/
|
||||
|
||||
#define APCI1710_16BIT_COUNTER 0x10
|
||||
#define APCI1710_32BIT_COUNTER 0x0
|
||||
#define APCI1710_QUADRUPLE_MODE 0x0
|
||||
#define APCI1710_DOUBLE_MODE 0x3
|
||||
#define APCI1710_SIMPLE_MODE 0xF
|
||||
#define APCI1710_DIRECT_MODE 0x80
|
||||
#define APCI1710_HYSTERESIS_ON 0x60
|
||||
#define APCI1710_HYSTERESIS_OFF 0x0
|
||||
#define APCI1710_INCREMENT 0x60
|
||||
#define APCI1710_DECREMENT 0x0
|
||||
#define APCI1710_LATCH_COUNTER 0x1
|
||||
#define APCI1710_CLEAR_COUNTER 0x0
|
||||
#define APCI1710_LOW 0x0
|
||||
#define APCI1710_HIGH 0x1
|
||||
|
||||
/*********************/
|
||||
/* Version 0600-0229 */
|
||||
/*********************/
|
||||
#define APCI1710_HIGH_EDGE_CLEAR_COUNTER 0x0
|
||||
#define APCI1710_HIGH_EDGE_LATCH_COUNTER 0x1
|
||||
#define APCI1710_LOW_EDGE_CLEAR_COUNTER 0x2
|
||||
#define APCI1710_LOW_EDGE_LATCH_COUNTER 0x3
|
||||
#define APCI1710_HIGH_EDGE_LATCH_AND_CLEAR_COUNTER 0x4
|
||||
#define APCI1710_LOW_EDGE_LATCH_AND_CLEAR_COUNTER 0x5
|
||||
#define APCI1710_SOURCE_0 0x0
|
||||
#define APCI1710_SOURCE_1 0x1
|
||||
|
||||
#define APCI1710_30MHZ 30
|
||||
#define APCI1710_33MHZ 33
|
||||
#define APCI1710_40MHZ 40
|
||||
|
||||
#define APCI1710_ENABLE_LATCH_INT 0x80
|
||||
#define APCI1710_DISABLE_LATCH_INT (~APCI1710_ENABLE_LATCH_INT)
|
||||
|
||||
#define APCI1710_INDEX_LATCH_COUNTER 0x10
|
||||
#define APCI1710_INDEX_AUTO_MODE 0x8
|
||||
#define APCI1710_ENABLE_INDEX 0x4
|
||||
#define APCI1710_DISABLE_INDEX (~APCI1710_ENABLE_INDEX)
|
||||
#define APCI1710_ENABLE_LATCH_AND_CLEAR 0x8
|
||||
#define APCI1710_DISABLE_LATCH_AND_CLEAR (~APCI1710_ENABLE_LATCH_AND_CLEAR)
|
||||
#define APCI1710_SET_LOW_INDEX_LEVEL 0x4
|
||||
#define APCI1710_SET_HIGH_INDEX_LEVEL (~APCI1710_SET_LOW_INDEX_LEVEL)
|
||||
#define APCI1710_INVERT_INDEX_RFERENCE 0x2
|
||||
#define APCI1710_DEFAULT_INDEX_RFERENCE (~APCI1710_INVERT_INDEX_RFERENCE)
|
||||
|
||||
#define APCI1710_ENABLE_INDEX_INT 0x1
|
||||
#define APCI1710_DISABLE_INDEX_INT (~APCI1710_ENABLE_INDEX_INT)
|
||||
|
||||
#define APCI1710_ENABLE_FREQUENCY 0x4
|
||||
#define APCI1710_DISABLE_FREQUENCY (~APCI1710_ENABLE_FREQUENCY)
|
||||
|
||||
#define APCI1710_ENABLE_FREQUENCY_INT 0x8
|
||||
#define APCI1710_DISABLE_FREQUENCY_INT (~APCI1710_ENABLE_FREQUENCY_INT)
|
||||
|
||||
#define APCI1710_ENABLE_40MHZ_FREQUENCY 0x40
|
||||
#define APCI1710_DISABLE_40MHZ_FREQUENCY (~APCI1710_ENABLE_40MHZ_FREQUENCY)
|
||||
|
||||
#define APCI1710_ENABLE_40MHZ_FILTER 0x80
|
||||
#define APCI1710_DISABLE_40MHZ_FILTER (~APCI1710_ENABLE_40MHZ_FILTER)
|
||||
|
||||
#define APCI1710_ENABLE_COMPARE_INT 0x2
|
||||
#define APCI1710_DISABLE_COMPARE_INT (~APCI1710_ENABLE_COMPARE_INT)
|
||||
|
||||
#define APCI1710_ENABLE_INDEX_ACTION 0x20
|
||||
#define APCI1710_DISABLE_INDEX_ACTION (~APCI1710_ENABLE_INDEX_ACTION)
|
||||
#define APCI1710_REFERENCE_HIGH 0x40
|
||||
#define APCI1710_REFERENCE_LOW (~APCI1710_REFERENCE_HIGH)
|
||||
|
||||
#define APCI1710_TOR_GATE_LOW 0x40
|
||||
#define APCI1710_TOR_GATE_HIGH (~APCI1710_TOR_GATE_LOW)
|
||||
|
||||
/* INSN CONFIG */
|
||||
#define APCI1710_INCCPT_INITCOUNTER 100
|
||||
#define APCI1710_INCCPT_COUNTERAUTOTEST 101
|
||||
#define APCI1710_INCCPT_INITINDEX 102
|
||||
#define APCI1710_INCCPT_INITREFERENCE 103
|
||||
#define APCI1710_INCCPT_INITEXTERNALSTROBE 104
|
||||
#define APCI1710_INCCPT_INITCOMPARELOGIC 105
|
||||
#define APCI1710_INCCPT_INITFREQUENCYMEASUREMENT 106
|
||||
|
||||
/* INSN READ */
|
||||
#define APCI1710_INCCPT_READLATCHREGISTERSTATUS 200
|
||||
#define APCI1710_INCCPT_READLATCHREGISTERVALUE 201
|
||||
#define APCI1710_INCCPT_READ16BITCOUNTERVALUE 202
|
||||
#define APCI1710_INCCPT_READ32BITCOUNTERVALUE 203
|
||||
#define APCI1710_INCCPT_GETINDEXSTATUS 204
|
||||
#define APCI1710_INCCPT_GETREFERENCESTATUS 205
|
||||
#define APCI1710_INCCPT_GETUASSTATUS 206
|
||||
#define APCI1710_INCCPT_GETCBSTATUS 207
|
||||
#define APCI1710_INCCPT_GET16BITCBSTATUS 208
|
||||
#define APCI1710_INCCPT_GETUDSTATUS 209
|
||||
#define APCI1710_INCCPT_GETINTERRUPTUDLATCHEDSTATUS 210
|
||||
#define APCI1710_INCCPT_READFREQUENCYMEASUREMENT 211
|
||||
#define APCI1710_INCCPT_READINTERRUPT 212
|
||||
|
||||
/* INSN BITS */
|
||||
#define APCI1710_INCCPT_CLEARCOUNTERVALUE 300
|
||||
#define APCI1710_INCCPT_CLEARALLCOUNTERVALUE 301
|
||||
#define APCI1710_INCCPT_SETINPUTFILTER 302
|
||||
#define APCI1710_INCCPT_LATCHCOUNTER 303
|
||||
#define APCI1710_INCCPT_SETINDEXANDREFERENCESOURCE 304
|
||||
#define APCI1710_INCCPT_SETDIGITALCHLON 305
|
||||
#define APCI1710_INCCPT_SETDIGITALCHLOFF 306
|
||||
|
||||
/* INSN WRITE */
|
||||
#define APCI1710_INCCPT_ENABLELATCHINTERRUPT 400
|
||||
#define APCI1710_INCCPT_DISABLELATCHINTERRUPT 401
|
||||
#define APCI1710_INCCPT_WRITE16BITCOUNTERVALUE 402
|
||||
#define APCI1710_INCCPT_WRITE32BITCOUNTERVALUE 403
|
||||
#define APCI1710_INCCPT_ENABLEINDEX 404
|
||||
#define APCI1710_INCCPT_DISABLEINDEX 405
|
||||
#define APCI1710_INCCPT_ENABLECOMPARELOGIC 406
|
||||
#define APCI1710_INCCPT_DISABLECOMPARELOGIC 407
|
||||
#define APCI1710_INCCPT_ENABLEFREQUENCYMEASUREMENT 408
|
||||
#define APCI1710_INCCPT_DISABLEFREQUENCYMEASUREMENT 409
|
||||
|
||||
/************ Main Functions *************/
|
||||
INT i_APCI1710_InsnConfigINCCPT(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int * data);
|
||||
|
||||
INT i_APCI1710_InsnBitsINCCPT(struct comedi_device *dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn *insn, unsigned int * data);
|
||||
|
||||
INT i_APCI1710_InsnWriteINCCPT(struct comedi_device *dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn *insn, unsigned int * data);
|
||||
|
||||
INT i_APCI1710_InsnReadINCCPT(struct comedi_device *dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn *insn, unsigned int * data);
|
||||
|
||||
/*********** Supplementary Functions********/
|
||||
|
||||
/* INSN CONFIG */
|
||||
INT i_APCI1710_InitCounter(struct comedi_device *dev,
|
||||
BYTE b_ModulNbr,
|
||||
BYTE b_CounterRange,
|
||||
BYTE b_FirstCounterModus,
|
||||
BYTE b_FirstCounterOption,
|
||||
BYTE b_SecondCounterModus,
|
||||
BYTE b_SecondCounterOption);
|
||||
|
||||
INT i_APCI1710_CounterAutoTest(struct comedi_device *dev, PBYTE pb_TestStatus);
|
||||
|
||||
INT i_APCI1710_InitIndex(struct comedi_device *dev,
|
||||
BYTE b_ModulNbr,
|
||||
BYTE b_ReferenceAction,
|
||||
BYTE b_IndexOperation, BYTE b_AutoMode,
|
||||
BYTE b_InterruptEnable);
|
||||
|
||||
INT i_APCI1710_InitReference(struct comedi_device *dev,
|
||||
BYTE b_ModulNbr, BYTE b_ReferenceLevel);
|
||||
|
||||
INT i_APCI1710_InitExternalStrobe(struct comedi_device *dev,
|
||||
BYTE b_ModulNbr, BYTE b_ExternalStrobe,
|
||||
BYTE b_ExternalStrobeLevel);
|
||||
|
||||
INT i_APCI1710_InitCompareLogic(struct comedi_device *dev,
|
||||
BYTE b_ModulNbr, UINT ui_CompareValue);
|
||||
|
||||
INT i_APCI1710_InitFrequencyMeasurement(struct comedi_device *dev,
|
||||
BYTE b_ModulNbr,
|
||||
BYTE b_PCIInputClock,
|
||||
BYTE b_TimingUnity,
|
||||
ULONG ul_TimingInterval,
|
||||
PULONG pul_RealTimingInterval);
|
||||
|
||||
/* INSN BITS */
|
||||
INT i_APCI1710_ClearCounterValue(struct comedi_device *dev, BYTE b_ModulNbr);
|
||||
|
||||
INT i_APCI1710_ClearAllCounterValue(struct comedi_device *dev);
|
||||
|
||||
INT i_APCI1710_SetInputFilter(struct comedi_device *dev,
|
||||
BYTE b_ModulNbr, BYTE b_PCIInputClock,
|
||||
BYTE b_Filter);
|
||||
|
||||
INT i_APCI1710_LatchCounter(struct comedi_device *dev,
|
||||
BYTE b_ModulNbr, BYTE b_LatchReg);
|
||||
|
||||
INT i_APCI1710_SetIndexAndReferenceSource(struct comedi_device *dev,
|
||||
BYTE b_ModulNbr,
|
||||
BYTE b_SourceSelection);
|
||||
|
||||
INT i_APCI1710_SetDigitalChlOn(struct comedi_device *dev, BYTE b_ModulNbr);
|
||||
|
||||
INT i_APCI1710_SetDigitalChlOff(struct comedi_device *dev, BYTE b_ModulNbr);
|
||||
|
||||
/* INSN WRITE */
|
||||
INT i_APCI1710_EnableLatchInterrupt(struct comedi_device *dev, BYTE b_ModulNbr);
|
||||
|
||||
INT i_APCI1710_DisableLatchInterrupt(struct comedi_device *dev, BYTE b_ModulNbr);
|
||||
|
||||
INT i_APCI1710_Write16BitCounterValue(struct comedi_device *dev,
|
||||
BYTE b_ModulNbr, BYTE b_SelectedCounter,
|
||||
UINT ui_WriteValue);
|
||||
|
||||
INT i_APCI1710_Write32BitCounterValue(struct comedi_device *dev,
|
||||
BYTE b_ModulNbr, ULONG ul_WriteValue);
|
||||
|
||||
INT i_APCI1710_EnableIndex(struct comedi_device *dev, BYTE b_ModulNbr);
|
||||
|
||||
INT i_APCI1710_DisableIndex(struct comedi_device *dev, BYTE b_ModulNbr);
|
||||
|
||||
INT i_APCI1710_EnableCompareLogic(struct comedi_device *dev, BYTE b_ModulNbr);
|
||||
|
||||
INT i_APCI1710_DisableCompareLogic(struct comedi_device *dev, BYTE b_ModulNbr);
|
||||
|
||||
INT i_APCI1710_EnableFrequencyMeasurement(struct comedi_device *dev,
|
||||
BYTE b_ModulNbr,
|
||||
BYTE b_InterruptEnable);
|
||||
|
||||
INT i_APCI1710_DisableFrequencyMeasurement(struct comedi_device *dev,
|
||||
BYTE b_ModulNbr);
|
||||
|
||||
/* INSN READ */
|
||||
INT i_APCI1710_ReadLatchRegisterStatus(struct comedi_device *dev,
|
||||
BYTE b_ModulNbr, BYTE b_LatchReg,
|
||||
PBYTE pb_LatchStatus);
|
||||
|
||||
INT i_APCI1710_ReadLatchRegisterValue(struct comedi_device *dev,
|
||||
BYTE b_ModulNbr, BYTE b_LatchReg,
|
||||
PULONG pul_LatchValue);
|
||||
|
||||
INT i_APCI1710_Read16BitCounterValue(struct comedi_device *dev,
|
||||
BYTE b_ModulNbr, BYTE b_SelectedCounter,
|
||||
PUINT pui_CounterValue);
|
||||
|
||||
INT i_APCI1710_Read32BitCounterValue(struct comedi_device *dev,
|
||||
BYTE b_ModulNbr, PULONG pul_CounterValue);
|
||||
|
||||
INT i_APCI1710_GetIndexStatus(struct comedi_device *dev,
|
||||
BYTE b_ModulNbr, PBYTE pb_IndexStatus);
|
||||
|
||||
INT i_APCI1710_GetReferenceStatus(struct comedi_device *dev,
|
||||
BYTE b_ModulNbr, PBYTE pb_ReferenceStatus);
|
||||
|
||||
INT i_APCI1710_GetUASStatus(struct comedi_device *dev,
|
||||
BYTE b_ModulNbr, PBYTE pb_UASStatus);
|
||||
|
||||
INT i_APCI1710_GetCBStatus(struct comedi_device *dev,
|
||||
BYTE b_ModulNbr, PBYTE pb_CBStatus);
|
||||
|
||||
INT i_APCI1710_Get16BitCBStatus(struct comedi_device *dev,
|
||||
BYTE b_ModulNbr, PBYTE pb_CBStatusCounter0,
|
||||
PBYTE pb_CBStatusCounter1);
|
||||
|
||||
INT i_APCI1710_GetUDStatus(struct comedi_device *dev,
|
||||
BYTE b_ModulNbr, PBYTE pb_UDStatus);
|
||||
|
||||
INT i_APCI1710_GetInterruptUDLatchedStatus(struct comedi_device *dev,
|
||||
BYTE b_ModulNbr, PBYTE pb_UDStatus);
|
||||
|
||||
INT i_APCI1710_ReadFrequencyMeasurement(struct comedi_device *dev,
|
||||
BYTE b_ModulNbr,
|
||||
PBYTE pb_Status, PBYTE pb_UDStatus,
|
||||
PULONG pul_ReadValue);
|
|
@ -0,0 +1,861 @@
|
|||
/**
|
||||
@verbatim
|
||||
|
||||
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
|
||||
ADDI-DATA GmbH
|
||||
Dieselstrasse 3
|
||||
D-77833 Ottersweier
|
||||
Tel: +19(0)7223/9493-0
|
||||
Fax: +49(0)7223/9493-92
|
||||
http://www.addi-data-com
|
||||
info@addi-data.com
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
You shoud also find the complete GPL in the COPYING file accompanying this source code.
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
/*
|
||||
|
||||
+-----------------------------------------------------------------------+
|
||||
| (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
|
||||
+-----------------------------------------------------------------------+
|
||||
| Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
|
||||
| Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
|
||||
+-----------------------------------------------------------------------+
|
||||
| Project : API APCI1710 | Compiler : gcc |
|
||||
| Module name : Inp_CPT.C | Version : 2.96 |
|
||||
+-------------------------------+---------------------------------------+
|
||||
| Project manager: Eric Stolz | Date : 02/12/2002 |
|
||||
+-----------------------------------------------------------------------+
|
||||
| Description : APCI-1710 pulse encoder module |
|
||||
| |
|
||||
| |
|
||||
+-----------------------------------------------------------------------+
|
||||
| UPDATES |
|
||||
+-----------------------------------------------------------------------+
|
||||
| Date | Author | Description of updates |
|
||||
+----------+-----------+------------------------------------------------+
|
||||
| | | |
|
||||
|----------|-----------|------------------------------------------------|
|
||||
| 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |
|
||||
| | | available |
|
||||
+-----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Included files |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include "APCI1710_Inp_cpt.h"
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : _INT_ i_APCI1710_InitPulseEncoder |
|
||||
| (BYTE_ b_BoardHandle, |
|
||||
| BYTE_ b_ModulNbr, |
|
||||
| BYTE_ b_PulseEncoderNbr, |
|
||||
| BYTE_ b_InputLevelSelection, |
|
||||
| BYTE_ b_TriggerOutputAction, |
|
||||
| ULONG_ ul_StartValue) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Configure the pulse encoder operating mode selected via|
|
||||
| b_ModulNbr and b_PulseEncoderNbr. The pulse encoder |
|
||||
| after each pulse decrement the counter value from 1. |
|
||||
| |
|
||||
| You must calling this function be for you call any |
|
||||
| other function witch access of pulse encoders. |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|
|
||||
| BYTE_ b_ModulNbr : Module number to |
|
||||
| configure (0 to 3) |
|
||||
| BYTE_ b_PulseEncoderNbr : Pulse encoder selection |
|
||||
| (0 to 3) |
|
||||
| BYTE_ b_InputLevelSelection : Input level selection |
|
||||
| (0 or 1) |
|
||||
| 0 : Set pulse encoder|
|
||||
| count the the low|
|
||||
| level pulse. |
|
||||
| 1 : Set pulse encoder|
|
||||
| count the the |
|
||||
| high level pulse.|
|
||||
| BYTE_ b_TriggerOutputAction : Digital TRIGGER output |
|
||||
| action |
|
||||
| 0 : No action |
|
||||
| 1 : Set the trigger |
|
||||
| output to "1" |
|
||||
| (high) after the |
|
||||
| passage from 1 to|
|
||||
| 0 from pulse |
|
||||
| encoder. |
|
||||
| 2 : Set the trigger |
|
||||
| output to "0" |
|
||||
| (low) after the |
|
||||
| passage from 1 to|
|
||||
| 0 from pulse |
|
||||
| encoder |
|
||||
| ULONG_ ul_StartValue : Pulse encoder start value|
|
||||
| (1 to 4294967295)
|
||||
b_ModulNbr =(BYTE) CR_AREF(insn->chanspec);
|
||||
b_PulseEncoderNbr =(BYTE) data[0];
|
||||
b_InputLevelSelection =(BYTE) data[1];
|
||||
b_TriggerOutputAction =(BYTE) data[2];
|
||||
ul_StartValue =(ULONG) data[3];
|
||||
|
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : - |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : 0: No error |
|
||||
| -1: The handle parameter of the board is wrong |
|
||||
| -2: The module is not a pulse encoder module |
|
||||
| -3: Pulse encoder selection is wrong |
|
||||
| -4: Input level selection is wrong |
|
||||
| -5: Digital TRIGGER output action selection is wrong |
|
||||
| -6: Pulse encoder start value is wrong |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
INT i_APCI1710_InsnConfigInitPulseEncoder(struct comedi_device * dev,
|
||||
struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
INT i_ReturnValue = 0;
|
||||
DWORD dw_IntRegister;
|
||||
|
||||
BYTE b_ModulNbr;
|
||||
BYTE b_PulseEncoderNbr;
|
||||
BYTE b_InputLevelSelection;
|
||||
BYTE b_TriggerOutputAction;
|
||||
ULONG ul_StartValue;
|
||||
|
||||
b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
|
||||
b_PulseEncoderNbr = (BYTE) data[0];
|
||||
b_InputLevelSelection = (BYTE) data[1];
|
||||
b_TriggerOutputAction = (BYTE) data[2];
|
||||
ul_StartValue = (ULONG) data[3];
|
||||
|
||||
i_ReturnValue = insn->n;
|
||||
|
||||
/***********************************/
|
||||
/* Test the selected module number */
|
||||
/***********************************/
|
||||
|
||||
if (b_ModulNbr <= 3) {
|
||||
/*************************/
|
||||
/* Test if pulse encoder */
|
||||
/*************************/
|
||||
|
||||
if ((devpriv->s_BoardInfos.
|
||||
dw_MolduleConfiguration[b_ModulNbr] &
|
||||
APCI1710_PULSE_ENCODER) ==
|
||||
APCI1710_PULSE_ENCODER) {
|
||||
/******************************************/
|
||||
/* Test the selected pulse encoder number */
|
||||
/******************************************/
|
||||
|
||||
if (b_PulseEncoderNbr <= 3) {
|
||||
/************************/
|
||||
/* Test the input level */
|
||||
/************************/
|
||||
|
||||
if ((b_InputLevelSelection == 0)
|
||||
|| (b_InputLevelSelection == 1)) {
|
||||
/*******************************************/
|
||||
/* Test the ouput TRIGGER action selection */
|
||||
/*******************************************/
|
||||
|
||||
if ((b_TriggerOutputAction <= 2)
|
||||
|| (b_PulseEncoderNbr > 0)) {
|
||||
if (ul_StartValue > 1) {
|
||||
|
||||
dw_IntRegister =
|
||||
inl(devpriv->
|
||||
s_BoardInfos.
|
||||
ui_Address +
|
||||
20 +
|
||||
(64 * b_ModulNbr));
|
||||
|
||||
/***********************/
|
||||
/* Set the start value */
|
||||
/***********************/
|
||||
|
||||
outl(ul_StartValue,
|
||||
devpriv->
|
||||
s_BoardInfos.
|
||||
ui_Address +
|
||||
(b_PulseEncoderNbr
|
||||
* 4) +
|
||||
(64 * b_ModulNbr));
|
||||
|
||||
/***********************/
|
||||
/* Set the input level */
|
||||
/***********************/
|
||||
devpriv->
|
||||
s_ModuleInfo
|
||||
[b_ModulNbr].
|
||||
s_PulseEncoderModuleInfo.
|
||||
dw_SetRegister =
|
||||
(devpriv->
|
||||
s_ModuleInfo
|
||||
[b_ModulNbr].
|
||||
s_PulseEncoderModuleInfo.
|
||||
dw_SetRegister &
|
||||
(0xFFFFFFFFUL -
|
||||
(1UL << (8 + b_PulseEncoderNbr)))) | ((1UL & (~b_InputLevelSelection)) << (8 + b_PulseEncoderNbr));
|
||||
|
||||
/*******************************/
|
||||
/* Test if output trigger used */
|
||||
/*******************************/
|
||||
|
||||
if ((b_TriggerOutputAction > 0) && (b_PulseEncoderNbr > 1)) {
|
||||
/****************************/
|
||||
/* Enable the output action */
|
||||
/****************************/
|
||||
|
||||
devpriv->
|
||||
s_ModuleInfo
|
||||
[b_ModulNbr].
|
||||
s_PulseEncoderModuleInfo.
|
||||
dw_SetRegister
|
||||
=
|
||||
devpriv->
|
||||
s_ModuleInfo
|
||||
[b_ModulNbr].
|
||||
s_PulseEncoderModuleInfo.
|
||||
dw_SetRegister
|
||||
| (1UL
|
||||
<< (4 + b_PulseEncoderNbr));
|
||||
|
||||
/*********************************/
|
||||
/* Set the output TRIGGER action */
|
||||
/*********************************/
|
||||
|
||||
devpriv->
|
||||
s_ModuleInfo
|
||||
[b_ModulNbr].
|
||||
s_PulseEncoderModuleInfo.
|
||||
dw_SetRegister
|
||||
=
|
||||
(devpriv->
|
||||
s_ModuleInfo
|
||||
[b_ModulNbr].
|
||||
s_PulseEncoderModuleInfo.
|
||||
dw_SetRegister
|
||||
&
|
||||
(0xFFFFFFFFUL
|
||||
-
|
||||
(1UL << (12 + b_PulseEncoderNbr)))) | ((1UL & (b_TriggerOutputAction - 1)) << (12 + b_PulseEncoderNbr));
|
||||
} else {
|
||||
/*****************************/
|
||||
/* Disable the output action */
|
||||
/*****************************/
|
||||
|
||||
devpriv->
|
||||
s_ModuleInfo
|
||||
[b_ModulNbr].
|
||||
s_PulseEncoderModuleInfo.
|
||||
dw_SetRegister
|
||||
=
|
||||
devpriv->
|
||||
s_ModuleInfo
|
||||
[b_ModulNbr].
|
||||
s_PulseEncoderModuleInfo.
|
||||
dw_SetRegister
|
||||
&
|
||||
(0xFFFFFFFFUL
|
||||
-
|
||||
(1UL << (4 + b_PulseEncoderNbr)));
|
||||
}
|
||||
|
||||
/*************************/
|
||||
/* Set the configuration */
|
||||
/*************************/
|
||||
|
||||
outl(devpriv->
|
||||
s_ModuleInfo
|
||||
[b_ModulNbr].
|
||||
s_PulseEncoderModuleInfo.
|
||||
dw_SetRegister,
|
||||
devpriv->
|
||||
s_BoardInfos.
|
||||
ui_Address +
|
||||
20 +
|
||||
(64 * b_ModulNbr));
|
||||
|
||||
devpriv->
|
||||
s_ModuleInfo
|
||||
[b_ModulNbr].
|
||||
s_PulseEncoderModuleInfo.
|
||||
s_PulseEncoderInfo
|
||||
[b_PulseEncoderNbr].
|
||||
b_PulseEncoderInit
|
||||
= 1;
|
||||
} else {
|
||||
/**************************************/
|
||||
/* Pulse encoder start value is wrong */
|
||||
/**************************************/
|
||||
|
||||
DPRINTK("Pulse encoder start value is wrong\n");
|
||||
i_ReturnValue = -6;
|
||||
}
|
||||
} else {
|
||||
/****************************************************/
|
||||
/* Digital TRIGGER output action selection is wrong */
|
||||
/****************************************************/
|
||||
|
||||
DPRINTK("Digital TRIGGER output action selection is wrong\n");
|
||||
i_ReturnValue = -5;
|
||||
}
|
||||
} else {
|
||||
/**********************************/
|
||||
/* Input level selection is wrong */
|
||||
/**********************************/
|
||||
|
||||
DPRINTK("Input level selection is wrong\n");
|
||||
i_ReturnValue = -4;
|
||||
}
|
||||
} else {
|
||||
/************************************/
|
||||
/* Pulse encoder selection is wrong */
|
||||
/************************************/
|
||||
|
||||
DPRINTK("Pulse encoder selection is wrong\n");
|
||||
i_ReturnValue = -3;
|
||||
}
|
||||
} else {
|
||||
/********************************************/
|
||||
/* The module is not a pulse encoder module */
|
||||
/********************************************/
|
||||
|
||||
DPRINTK("The module is not a pulse encoder module\n");
|
||||
i_ReturnValue = -2;
|
||||
}
|
||||
} else {
|
||||
/********************************************/
|
||||
/* The module is not a pulse encoder module */
|
||||
/********************************************/
|
||||
|
||||
DPRINTK("The module is not a pulse encoder module\n");
|
||||
i_ReturnValue = -2;
|
||||
}
|
||||
|
||||
return (i_ReturnValue);
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : _INT_ i_APCI1710_EnablePulseEncoder |
|
||||
| (BYTE_ b_BoardHandle, |
|
||||
| BYTE_ b_ModulNbr, |
|
||||
| BYTE_ b_PulseEncoderNbr, |
|
||||
| BYTE_ b_CycleSelection, |
|
||||
| BYTE_ b_InterruptHandling) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Enableor disable the selected pulse encoder (b_PulseEncoderNbr) |
|
||||
| from selected module (b_ModulNbr). Each input pulse |
|
||||
| decrement the pulse encoder counter value from 1. |
|
||||
| If you enabled the interrupt (b_InterruptHandling), a |
|
||||
| interrupt is generated when the pulse encoder has run |
|
||||
| down. |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|
|
||||
| BYTE_ b_ModulNbr : Module number to |
|
||||
| configure (0 to 3) |
|
||||
| BYTE_ b_PulseEncoderNbr : Pulse encoder selection |
|
||||
| (0 to 3) |
|
||||
| BYTE_ b_CycleSelection : APCI1710_CONTINUOUS: |
|
||||
| Each time the |
|
||||
| counting value is set|
|
||||
| on "0", the pulse |
|
||||
| encoder load the |
|
||||
| start value after |
|
||||
| the next pulse. |
|
||||
| APCI1710_SINGLE: |
|
||||
| If the counter is set|
|
||||
| on "0", the pulse |
|
||||
| encoder is stopped. |
|
||||
| BYTE_ b_InterruptHandling : Interrupts can be |
|
||||
| generated, when the pulse|
|
||||
| encoder has run down. |
|
||||
| With this parameter the |
|
||||
| user decides if |
|
||||
| interrupts are used or |
|
||||
| not. |
|
||||
| APCI1710_ENABLE: |
|
||||
| Interrupts are enabled |
|
||||
| APCI1710_DISABLE: |
|
||||
| Interrupts are disabled
|
||||
|
||||
b_ModulNbr =(BYTE) CR_AREF(insn->chanspec);
|
||||
b_Action =(BYTE) data[0];
|
||||
b_PulseEncoderNbr =(BYTE) data[1];
|
||||
b_CycleSelection =(BYTE) data[2];
|
||||
b_InterruptHandling =(BYTE) data[3];|
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : - |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : 0: No error |
|
||||
| -1: The handle parameter of the board is wrong |
|
||||
| -2: Module selection is wrong |
|
||||
| -3: Pulse encoder selection is wrong |
|
||||
| -4: Pulse encoder not initialised. |
|
||||
| See function "i_APCI1710_InitPulseEncoder" |
|
||||
| -5: Cycle selection mode is wrong |
|
||||
| -6: Interrupt handling mode is wrong |
|
||||
| -7: Interrupt routine not installed. |
|
||||
| See function "i_APCI1710_SetBoardIntRoutineX" |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
INT i_APCI1710_InsnWriteEnableDisablePulseEncoder(struct comedi_device * dev,
|
||||
struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
INT i_ReturnValue = 0;
|
||||
BYTE b_ModulNbr;
|
||||
BYTE b_PulseEncoderNbr;
|
||||
BYTE b_CycleSelection;
|
||||
BYTE b_InterruptHandling;
|
||||
BYTE b_Action;
|
||||
|
||||
i_ReturnValue = insn->n;
|
||||
b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
|
||||
b_Action = (BYTE) data[0];
|
||||
b_PulseEncoderNbr = (BYTE) data[1];
|
||||
b_CycleSelection = (BYTE) data[2];
|
||||
b_InterruptHandling = (BYTE) data[3];
|
||||
|
||||
/***********************************/
|
||||
/* Test the selected module number */
|
||||
/***********************************/
|
||||
|
||||
if (b_ModulNbr <= 3) {
|
||||
/******************************************/
|
||||
/* Test the selected pulse encoder number */
|
||||
/******************************************/
|
||||
|
||||
if (b_PulseEncoderNbr <= 3) {
|
||||
/*************************************/
|
||||
/* Test if pulse encoder initialised */
|
||||
/*************************************/
|
||||
|
||||
if (devpriv->s_ModuleInfo[b_ModulNbr].
|
||||
s_PulseEncoderModuleInfo.
|
||||
s_PulseEncoderInfo[b_PulseEncoderNbr].
|
||||
b_PulseEncoderInit == 1) {
|
||||
switch (b_Action) {
|
||||
|
||||
case APCI1710_ENABLE:
|
||||
/****************************/
|
||||
/* Test the cycle selection */
|
||||
/****************************/
|
||||
|
||||
if (b_CycleSelection ==
|
||||
APCI1710_CONTINUOUS
|
||||
|| b_CycleSelection ==
|
||||
APCI1710_SINGLE) {
|
||||
/*******************************/
|
||||
/* Test the interrupt handling */
|
||||
/*******************************/
|
||||
|
||||
if (b_InterruptHandling ==
|
||||
APCI1710_ENABLE
|
||||
|| b_InterruptHandling
|
||||
== APCI1710_DISABLE) {
|
||||
/******************************/
|
||||
/* Test if interrupt not used */
|
||||
/******************************/
|
||||
|
||||
if (b_InterruptHandling
|
||||
==
|
||||
APCI1710_DISABLE)
|
||||
{
|
||||
/*************************/
|
||||
/* Disable the interrupt */
|
||||
/*************************/
|
||||
|
||||
devpriv->
|
||||
s_ModuleInfo
|
||||
[b_ModulNbr].
|
||||
s_PulseEncoderModuleInfo.
|
||||
dw_SetRegister
|
||||
=
|
||||
devpriv->
|
||||
s_ModuleInfo
|
||||
[b_ModulNbr].
|
||||
s_PulseEncoderModuleInfo.
|
||||
dw_SetRegister
|
||||
&
|
||||
(0xFFFFFFFFUL
|
||||
-
|
||||
(1UL << b_PulseEncoderNbr));
|
||||
} else {
|
||||
|
||||
/************************/
|
||||
/* Enable the interrupt */
|
||||
/************************/
|
||||
|
||||
devpriv->
|
||||
s_ModuleInfo
|
||||
[b_ModulNbr].
|
||||
s_PulseEncoderModuleInfo.
|
||||
dw_SetRegister
|
||||
=
|
||||
devpriv->
|
||||
s_ModuleInfo
|
||||
[b_ModulNbr].
|
||||
s_PulseEncoderModuleInfo.
|
||||
dw_SetRegister
|
||||
| (1UL
|
||||
<<
|
||||
b_PulseEncoderNbr);
|
||||
devpriv->tsk_Current = current; // Save the current process task structure
|
||||
|
||||
}
|
||||
|
||||
if (i_ReturnValue >= 0) {
|
||||
/***********************************/
|
||||
/* Enable or disable the interrupt */
|
||||
/***********************************/
|
||||
|
||||
outl(devpriv->
|
||||
s_ModuleInfo
|
||||
[b_ModulNbr].
|
||||
s_PulseEncoderModuleInfo.
|
||||
dw_SetRegister,
|
||||
devpriv->
|
||||
s_BoardInfos.
|
||||
ui_Address
|
||||
+ 20 +
|
||||
(64 * b_ModulNbr));
|
||||
|
||||
/****************************/
|
||||
/* Enable the pulse encoder */
|
||||
/****************************/
|
||||
devpriv->
|
||||
s_ModuleInfo
|
||||
[b_ModulNbr].
|
||||
s_PulseEncoderModuleInfo.
|
||||
dw_ControlRegister
|
||||
=
|
||||
devpriv->
|
||||
s_ModuleInfo
|
||||
[b_ModulNbr].
|
||||
s_PulseEncoderModuleInfo.
|
||||
dw_ControlRegister
|
||||
| (1UL
|
||||
<<
|
||||
b_PulseEncoderNbr);
|
||||
|
||||
/**********************/
|
||||
/* Set the cycle mode */
|
||||
/**********************/
|
||||
|
||||
devpriv->
|
||||
s_ModuleInfo
|
||||
[b_ModulNbr].
|
||||
s_PulseEncoderModuleInfo.
|
||||
dw_ControlRegister
|
||||
=
|
||||
(devpriv->
|
||||
s_ModuleInfo
|
||||
[b_ModulNbr].
|
||||
s_PulseEncoderModuleInfo.
|
||||
dw_ControlRegister
|
||||
&
|
||||
(0xFFFFFFFFUL
|
||||
-
|
||||
(1 << (b_PulseEncoderNbr + 4)))) | ((b_CycleSelection & 1UL) << (4 + b_PulseEncoderNbr));
|
||||
|
||||
/****************************/
|
||||
/* Enable the pulse encoder */
|
||||
/****************************/
|
||||
|
||||
outl(devpriv->
|
||||
s_ModuleInfo
|
||||
[b_ModulNbr].
|
||||
s_PulseEncoderModuleInfo.
|
||||
dw_ControlRegister,
|
||||
devpriv->
|
||||
s_BoardInfos.
|
||||
ui_Address
|
||||
+ 16 +
|
||||
(64 * b_ModulNbr));
|
||||
}
|
||||
} else {
|
||||
/************************************/
|
||||
/* Interrupt handling mode is wrong */
|
||||
/************************************/
|
||||
|
||||
DPRINTK("Interrupt handling mode is wrong\n");
|
||||
i_ReturnValue = -6;
|
||||
}
|
||||
} else {
|
||||
/*********************************/
|
||||
/* Cycle selection mode is wrong */
|
||||
/*********************************/
|
||||
|
||||
DPRINTK("Cycle selection mode is wrong\n");
|
||||
i_ReturnValue = -5;
|
||||
}
|
||||
break;
|
||||
|
||||
case APCI1710_DISABLE:
|
||||
devpriv->s_ModuleInfo[b_ModulNbr].
|
||||
s_PulseEncoderModuleInfo.
|
||||
dw_ControlRegister =
|
||||
devpriv->
|
||||
s_ModuleInfo[b_ModulNbr].
|
||||
s_PulseEncoderModuleInfo.
|
||||
dw_ControlRegister &
|
||||
(0xFFFFFFFFUL -
|
||||
(1UL << b_PulseEncoderNbr));
|
||||
|
||||
/*****************************/
|
||||
/* Disable the pulse encoder */
|
||||
/*****************************/
|
||||
|
||||
outl(devpriv->s_ModuleInfo[b_ModulNbr].
|
||||
s_PulseEncoderModuleInfo.
|
||||
dw_ControlRegister,
|
||||
devpriv->s_BoardInfos.
|
||||
ui_Address + 16 +
|
||||
(64 * b_ModulNbr));
|
||||
|
||||
break;
|
||||
} // switch End
|
||||
|
||||
} else {
|
||||
/*********************************/
|
||||
/* Pulse encoder not initialised */
|
||||
/*********************************/
|
||||
|
||||
DPRINTK("Pulse encoder not initialised\n");
|
||||
i_ReturnValue = -4;
|
||||
}
|
||||
} else {
|
||||
/************************************/
|
||||
/* Pulse encoder selection is wrong */
|
||||
/************************************/
|
||||
|
||||
DPRINTK("Pulse encoder selection is wrong\n");
|
||||
i_ReturnValue = -3;
|
||||
}
|
||||
} else {
|
||||
/*****************************/
|
||||
/* Module selection is wrong */
|
||||
/*****************************/
|
||||
|
||||
DPRINTK("Module selection is wrong\n");
|
||||
i_ReturnValue = -2;
|
||||
}
|
||||
|
||||
return (i_ReturnValue);
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : _INT_ i_APCI1710_ReadPulseEncoderStatus |
|
||||
| (BYTE_ b_BoardHandle, |
|
||||
| BYTE_ b_ModulNbr, |
|
||||
| BYTE_ b_PulseEncoderNbr, |
|
||||
| PBYTE_ pb_Status) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task APCI1710_PULSEENCODER_READ : Reads the pulse encoder status
|
||||
and valuefrom selected pulse |
|
||||
| encoder (b_PulseEncoderNbr) from selected module |
|
||||
| (b_ModulNbr). |
|
||||
+----------------------------------------------------------------------------+
|
||||
BYTE b_Type; data[0]
|
||||
APCI1710_PULSEENCODER_WRITE
|
||||
Writes a 32-bit value (ul_WriteValue) into the selected|
|
||||
| pulse encoder (b_PulseEncoderNbr) from selected module |
|
||||
| (b_ModulNbr). This operation set the new start pulse |
|
||||
| encoder value.
|
||||
APCI1710_PULSEENCODER_READ
|
||||
| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|
|
||||
| CRAREF() BYTE_ b_ModulNbr : Module number to |
|
||||
| configure (0 to 3) |
|
||||
| data[1] BYTE_ b_PulseEncoderNbr : Pulse encoder selection |
|
||||
| (0 to 3)
|
||||
APCI1710_PULSEENCODER_WRITE
|
||||
data[2] ULONG_ ul_WriteValue : 32-bit value to be |
|
||||
| written |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : PBYTE_ pb_Status : Pulse encoder status. |
|
||||
| 0 : No overflow occur|
|
||||
| 1 : Overflow occur
|
||||
PULONG_ pul_ReadValue : Pulse encoder value | |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : 0: No error |
|
||||
| -1: The handle parameter of the board is wrong |
|
||||
| -2: Module selection is wrong |
|
||||
| -3: Pulse encoder selection is wrong |
|
||||
| -4: Pulse encoder not initialised. |
|
||||
| See function "i_APCI1710_InitPulseEncoder" |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/*_INT_ i_APCI1710_ReadPulseEncoderStatus (BYTE_ b_BoardHandle,
|
||||
BYTE_ b_ModulNbr,
|
||||
BYTE_ b_PulseEncoderNbr,
|
||||
|
||||
PBYTE_ pb_Status)
|
||||
*/
|
||||
INT i_APCI1710_InsnBitsReadWritePulseEncoder(struct comedi_device * dev,
|
||||
struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
INT i_ReturnValue = 0;
|
||||
DWORD dw_StatusRegister;
|
||||
BYTE b_ModulNbr;
|
||||
BYTE b_PulseEncoderNbr;
|
||||
PBYTE pb_Status;
|
||||
BYTE b_Type;
|
||||
PULONG pul_ReadValue;
|
||||
ULONG ul_WriteValue;
|
||||
|
||||
i_ReturnValue = insn->n;
|
||||
b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
|
||||
b_Type = (BYTE) data[0];
|
||||
b_PulseEncoderNbr = (BYTE) data[1];
|
||||
pb_Status = (PBYTE) & data[0];
|
||||
pul_ReadValue = (PULONG) & data[1];
|
||||
|
||||
/***********************************/
|
||||
/* Test the selected module number */
|
||||
/***********************************/
|
||||
|
||||
if (b_ModulNbr <= 3) {
|
||||
/******************************************/
|
||||
/* Test the selected pulse encoder number */
|
||||
/******************************************/
|
||||
|
||||
if (b_PulseEncoderNbr <= 3) {
|
||||
/*************************************/
|
||||
/* Test if pulse encoder initialised */
|
||||
/*************************************/
|
||||
|
||||
if (devpriv->s_ModuleInfo[b_ModulNbr].
|
||||
s_PulseEncoderModuleInfo.
|
||||
s_PulseEncoderInfo[b_PulseEncoderNbr].
|
||||
b_PulseEncoderInit == 1) {
|
||||
|
||||
switch (b_Type) {
|
||||
case APCI1710_PULSEENCODER_READ:
|
||||
/****************************/
|
||||
/* Read the status register */
|
||||
/****************************/
|
||||
|
||||
dw_StatusRegister =
|
||||
inl(devpriv->s_BoardInfos.
|
||||
ui_Address + 16 +
|
||||
(64 * b_ModulNbr));
|
||||
|
||||
devpriv->s_ModuleInfo[b_ModulNbr].
|
||||
s_PulseEncoderModuleInfo.
|
||||
dw_StatusRegister = devpriv->
|
||||
s_ModuleInfo[b_ModulNbr].
|
||||
s_PulseEncoderModuleInfo.
|
||||
dw_StatusRegister |
|
||||
dw_StatusRegister;
|
||||
|
||||
*pb_Status =
|
||||
(BYTE) (devpriv->
|
||||
s_ModuleInfo[b_ModulNbr].
|
||||
s_PulseEncoderModuleInfo.
|
||||
dw_StatusRegister >> (1 +
|
||||
b_PulseEncoderNbr)) & 1;
|
||||
|
||||
devpriv->s_ModuleInfo[b_ModulNbr].
|
||||
s_PulseEncoderModuleInfo.
|
||||
dw_StatusRegister =
|
||||
devpriv->
|
||||
s_ModuleInfo[b_ModulNbr].
|
||||
s_PulseEncoderModuleInfo.
|
||||
dw_StatusRegister &
|
||||
(0xFFFFFFFFUL - (1 << (1 +
|
||||
b_PulseEncoderNbr)));
|
||||
|
||||
/******************/
|
||||
/* Read the value */
|
||||
/******************/
|
||||
|
||||
*pul_ReadValue =
|
||||
inl(devpriv->s_BoardInfos.
|
||||
ui_Address +
|
||||
(4 * b_PulseEncoderNbr) +
|
||||
(64 * b_ModulNbr));
|
||||
break;
|
||||
|
||||
case APCI1710_PULSEENCODER_WRITE:
|
||||
ul_WriteValue = (ULONG) data[2];
|
||||
/*******************/
|
||||
/* Write the value */
|
||||
/*******************/
|
||||
|
||||
outl(ul_WriteValue,
|
||||
devpriv->s_BoardInfos.
|
||||
ui_Address +
|
||||
(4 * b_PulseEncoderNbr) +
|
||||
(64 * b_ModulNbr));
|
||||
|
||||
} //end of switch
|
||||
} else {
|
||||
/*********************************/
|
||||
/* Pulse encoder not initialised */
|
||||
/*********************************/
|
||||
|
||||
DPRINTK("Pulse encoder not initialised\n");
|
||||
i_ReturnValue = -4;
|
||||
}
|
||||
} else {
|
||||
/************************************/
|
||||
/* Pulse encoder selection is wrong */
|
||||
/************************************/
|
||||
|
||||
DPRINTK("Pulse encoder selection is wrong\n");
|
||||
i_ReturnValue = -3;
|
||||
}
|
||||
} else {
|
||||
/*****************************/
|
||||
/* Module selection is wrong */
|
||||
/*****************************/
|
||||
|
||||
DPRINTK("Module selection is wrong\n");
|
||||
i_ReturnValue = -2;
|
||||
}
|
||||
|
||||
return (i_ReturnValue);
|
||||
}
|
||||
|
||||
INT i_APCI1710_InsnReadInterruptPulseEncoder(struct comedi_device * dev,
|
||||
struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
|
||||
data[0] = devpriv->s_InterruptParameters.
|
||||
s_FIFOInterruptParameters[devpriv->
|
||||
s_InterruptParameters.ui_Read].b_OldModuleMask;
|
||||
data[1] = devpriv->s_InterruptParameters.
|
||||
s_FIFOInterruptParameters[devpriv->
|
||||
s_InterruptParameters.ui_Read].ul_OldInterruptMask;
|
||||
data[2] = devpriv->s_InterruptParameters.
|
||||
s_FIFOInterruptParameters[devpriv->
|
||||
s_InterruptParameters.ui_Read].ul_OldCounterLatchValue;
|
||||
|
||||
/***************************/
|
||||
/* Increment the read FIFO */
|
||||
/***************************/
|
||||
|
||||
devpriv->s_InterruptParameters.
|
||||
ui_Read = (devpriv->
|
||||
s_InterruptParameters.ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
|
||||
|
||||
return insn->n;
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
*
|
||||
* ADDI-DATA GmbH
|
||||
* Dieselstrasse 3
|
||||
* D-77833 Ottersweier
|
||||
* Tel: +19(0)7223/9493-0
|
||||
* Fax: +49(0)7223/9493-92
|
||||
* http://www.addi-data-com
|
||||
* info@addi-data.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*/
|
||||
|
||||
#define APCI1710_SINGLE 0
|
||||
#define APCI1710_CONTINUOUS 1
|
||||
|
||||
#define APCI1710_PULSEENCODER_READ 0
|
||||
#define APCI1710_PULSEENCODER_WRITE 1
|
||||
|
||||
INT i_APCI1710_InsnConfigInitPulseEncoder(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
INT i_APCI1710_InsnWriteEnableDisablePulseEncoder(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
|
||||
/*
|
||||
* READ PULSE ENCODER FUNCTIONS
|
||||
*/
|
||||
INT i_APCI1710_InsnReadInterruptPulseEncoder(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
|
||||
/*
|
||||
* WRITE PULSE ENCODER FUNCTIONS
|
||||
*/
|
||||
INT i_APCI1710_InsnBitsReadWritePulseEncoder(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
*
|
||||
* ADDI-DATA GmbH
|
||||
* Dieselstrasse 3
|
||||
* D-77833 Ottersweier
|
||||
* Tel: +19(0)7223/9493-0
|
||||
* Fax: +49(0)7223/9493-92
|
||||
* http://www.addi-data-com
|
||||
* info@addi-data.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*/
|
||||
|
||||
#define APCI1710_30MHZ 30
|
||||
#define APCI1710_33MHZ 33
|
||||
#define APCI1710_40MHZ 40
|
||||
|
||||
#define APCI1710_PWM_INIT 0
|
||||
#define APCI1710_PWM_GETINITDATA 1
|
||||
|
||||
#define APCI1710_PWM_DISABLE 0
|
||||
#define APCI1710_PWM_ENABLE 1
|
||||
#define APCI1710_PWM_NEWTIMING 2
|
||||
|
||||
INT i_APCI1710_InsnConfigPWM(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
INT i_APCI1710_InitPWM(struct comedi_device *dev,
|
||||
BYTE b_ModulNbr,
|
||||
BYTE b_PWM,
|
||||
BYTE b_ClockSelection,
|
||||
BYTE b_TimingUnit,
|
||||
ULONG ul_LowTiming,
|
||||
ULONG ul_HighTiming,
|
||||
PULONG pul_RealLowTiming, PULONG pul_RealHighTiming);
|
||||
|
||||
INT i_APCI1710_GetPWMInitialisation(struct comedi_device *dev,
|
||||
BYTE b_ModulNbr,
|
||||
BYTE b_PWM,
|
||||
PBYTE pb_TimingUnit,
|
||||
PULONG pul_LowTiming,
|
||||
PULONG pul_HighTiming,
|
||||
PBYTE pb_StartLevel,
|
||||
PBYTE pb_StopMode,
|
||||
PBYTE pb_StopLevel,
|
||||
PBYTE pb_ExternGate,
|
||||
PBYTE pb_InterruptEnable, PBYTE pb_Enable);
|
||||
|
||||
INT i_APCI1710_InsnWritePWM(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
INT i_APCI1710_EnablePWM(struct comedi_device *dev,
|
||||
BYTE b_ModulNbr,
|
||||
BYTE b_PWM,
|
||||
BYTE b_StartLevel,
|
||||
BYTE b_StopMode,
|
||||
BYTE b_StopLevel, BYTE b_ExternGate,
|
||||
BYTE b_InterruptEnable);
|
||||
|
||||
INT i_APCI1710_SetNewPWMTiming(struct comedi_device *dev,
|
||||
BYTE b_ModulNbr,
|
||||
BYTE b_PWM, BYTE b_TimingUnit,
|
||||
ULONG ul_LowTiming, ULONG ul_HighTiming);
|
||||
|
||||
INT i_APCI1710_DisablePWM(struct comedi_device *dev, BYTE b_ModulNbr, BYTE b_PWM);
|
||||
|
||||
INT i_APCI1710_InsnReadGetPWMStatus(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
INT i_APCI1710_InsnBitsReadPWMInterrupt(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
|
@ -0,0 +1,848 @@
|
|||
/**
|
||||
@verbatim
|
||||
|
||||
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
|
||||
ADDI-DATA GmbH
|
||||
Dieselstrasse 3
|
||||
D-77833 Ottersweier
|
||||
Tel: +19(0)7223/9493-0
|
||||
Fax: +49(0)7223/9493-92
|
||||
http://www.addi-data-com
|
||||
info@addi-data.com
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
You shoud also find the complete GPL in the COPYING file accompanying this source code.
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
/*
|
||||
|
||||
+-----------------------------------------------------------------------+
|
||||
| (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
|
||||
+-----------------------------------------------------------------------+
|
||||
| Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
|
||||
| Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
|
||||
+-----------------------------------------------------------------------+
|
||||
| Project : API APCI1710 | Compiler : gcc |
|
||||
| Module name : SSI.C | Version : 2.96 |
|
||||
+-------------------------------+---------------------------------------+
|
||||
| Project manager: Eric Stolz | Date : 02/12/2002 |
|
||||
+-----------------------------------------------------------------------+
|
||||
| Description : APCI-1710 SSI counter module |
|
||||
| |
|
||||
| |
|
||||
+-----------------------------------------------------------------------+
|
||||
| UPDATES |
|
||||
+-----------------------------------------------------------------------+
|
||||
| Date | Author | Description of updates |
|
||||
+----------+-----------+------------------------------------------------+
|
||||
| 13/05/98 | S. Weber | SSI digital input / output implementation |
|
||||
|----------|-----------|------------------------------------------------|
|
||||
| 22/03/00 | C.Guinot | 0100/0226 -> 0200/0227 |
|
||||
| | | Änderung in InitSSI Funktion |
|
||||
| | | b_SSIProfile >= 2 anstatt b_SSIProfile > 2 |
|
||||
| | | |
|
||||
+-----------------------------------------------------------------------+
|
||||
| 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |
|
||||
| | | available |
|
||||
+-----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Included files |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include "APCI1710_Ssi.h"
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : _INT_ i_APCI1710_InitSSI |
|
||||
| (BYTE_ b_BoardHandle, |
|
||||
| BYTE_ b_ModulNbr, |
|
||||
| BYTE_ b_SSIProfile, |
|
||||
| BYTE_ b_PositionTurnLength, |
|
||||
| BYTE_ b_TurnCptLength, |
|
||||
| BYTE_ b_PCIInputClock, |
|
||||
| ULONG_ ul_SSIOutputClock, |
|
||||
| BYTE_ b_SSICountingMode) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Configure the SSI operating mode from selected module |
|
||||
| (b_ModulNbr). You must calling this function be for you|
|
||||
| call any other function witch access of SSI. |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|
|
||||
| BYTE_ b_ModulNbr : Module number to |
|
||||
| configure (0 to 3) |
|
||||
| BYTE_ b_SSIProfile : Selection from SSI |
|
||||
| profile length (2 to 32).|
|
||||
| BYTE_ b_PositionTurnLength : Selection from SSI |
|
||||
| position data length |
|
||||
| (1 to 31). |
|
||||
| BYTE_ b_TurnCptLength : Selection from SSI turn |
|
||||
| counter data length |
|
||||
| (1 to 31). |
|
||||
| BYTE b_PCIInputClock : Selection from PCI bus |
|
||||
| clock |
|
||||
| - APCI1710_30MHZ : |
|
||||
| The PC have a PCI bus |
|
||||
| clock from 30 MHz |
|
||||
| - APCI1710_33MHZ : |
|
||||
| The PC have a PCI bus |
|
||||
| clock from 33 MHz |
|
||||
| ULONG_ ul_SSIOutputClock : Selection from SSI output|
|
||||
| clock. |
|
||||
| From 229 to 5 000 000 Hz|
|
||||
| for 30 MHz selection. |
|
||||
| From 252 to 5 000 000 Hz|
|
||||
| for 33 MHz selection. |
|
||||
| BYTE b_SSICountingMode : SSI counting mode |
|
||||
| selection |
|
||||
| - APCI1710_BINARY_MODE : |
|
||||
| Binary counting mode. |
|
||||
| - APCI1710_GRAY_MODE : |
|
||||
| Gray counting mode.
|
||||
|
||||
b_ModulNbr = CR_AREF(insn->chanspec);
|
||||
b_SSIProfile = (BYTE) data[0];
|
||||
b_PositionTurnLength= (BYTE) data[1];
|
||||
b_TurnCptLength = (BYTE) data[2];
|
||||
b_PCIInputClock = (BYTE) data[3];
|
||||
ul_SSIOutputClock = (ULONG) data[4];
|
||||
b_SSICountingMode = (BYTE) data[5]; |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : - |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : 0: No error |
|
||||
| -1: The handle parameter of the board is wrong |
|
||||
| -2: The module parameter is wrong |
|
||||
| -3: The module is not a SSI module |
|
||||
| -4: The selected SSI profile length is wrong |
|
||||
| -5: The selected SSI position data length is wrong |
|
||||
| -6: The selected SSI turn counter data length is wrong |
|
||||
| -7: The selected PCI input clock is wrong |
|
||||
| -8: The selected SSI output clock is wrong |
|
||||
| -9: The selected SSI counting mode parameter is wrong |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
INT i_APCI1710_InsnConfigInitSSI(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
INT i_ReturnValue = 0;
|
||||
UINT ui_TimerValue;
|
||||
BYTE b_ModulNbr, b_SSIProfile, b_PositionTurnLength, b_TurnCptLength,
|
||||
b_PCIInputClock, b_SSICountingMode;
|
||||
ULONG ul_SSIOutputClock;
|
||||
|
||||
b_ModulNbr = CR_AREF(insn->chanspec);
|
||||
b_SSIProfile = (BYTE) data[0];
|
||||
b_PositionTurnLength = (BYTE) data[1];
|
||||
b_TurnCptLength = (BYTE) data[2];
|
||||
b_PCIInputClock = (BYTE) data[3];
|
||||
ul_SSIOutputClock = (ULONG) data[4];
|
||||
b_SSICountingMode = (BYTE) data[5];
|
||||
|
||||
i_ReturnValue = insn->n;
|
||||
/**************************/
|
||||
/* Test the module number */
|
||||
/**************************/
|
||||
|
||||
if (b_ModulNbr < 4) {
|
||||
/***********************/
|
||||
/* Test if SSI counter */
|
||||
/***********************/
|
||||
|
||||
if ((devpriv->s_BoardInfos.
|
||||
dw_MolduleConfiguration[b_ModulNbr] &
|
||||
0xFFFF0000UL) == APCI1710_SSI_COUNTER) {
|
||||
/*******************************/
|
||||
/* Test the SSI profile length */
|
||||
/*******************************/
|
||||
|
||||
// CG 22/03/00 b_SSIProfile >= 2 anstatt b_SSIProfile > 2
|
||||
if (b_SSIProfile >= 2 && b_SSIProfile < 33) {
|
||||
/*************************************/
|
||||
/* Test the SSI position data length */
|
||||
/*************************************/
|
||||
|
||||
if (b_PositionTurnLength > 0
|
||||
&& b_PositionTurnLength < 32) {
|
||||
/*****************************************/
|
||||
/* Test the SSI turn counter data length */
|
||||
/*****************************************/
|
||||
|
||||
if (b_TurnCptLength > 0
|
||||
&& b_TurnCptLength < 32) {
|
||||
/***************************/
|
||||
/* Test the profile length */
|
||||
/***************************/
|
||||
|
||||
if ((b_TurnCptLength +
|
||||
b_PositionTurnLength)
|
||||
<= b_SSIProfile) {
|
||||
/****************************/
|
||||
/* Test the PCI input clock */
|
||||
/****************************/
|
||||
|
||||
if (b_PCIInputClock ==
|
||||
APCI1710_30MHZ
|
||||
||
|
||||
b_PCIInputClock
|
||||
==
|
||||
APCI1710_33MHZ)
|
||||
{
|
||||
/*************************/
|
||||
/* Test the output clock */
|
||||
/*************************/
|
||||
|
||||
if ((b_PCIInputClock == APCI1710_30MHZ && (ul_SSIOutputClock > 228 && ul_SSIOutputClock <= 5000000UL)) || (b_PCIInputClock == APCI1710_33MHZ && (ul_SSIOutputClock > 251 && ul_SSIOutputClock <= 5000000UL))) {
|
||||
if (b_SSICountingMode == APCI1710_BINARY_MODE || b_SSICountingMode == APCI1710_GRAY_MODE) {
|
||||
/**********************/
|
||||
/* Save configuration */
|
||||
/**********************/
|
||||
devpriv->
|
||||
s_ModuleInfo
|
||||
[b_ModulNbr].
|
||||
s_SSICounterInfo.
|
||||
b_SSIProfile
|
||||
=
|
||||
b_SSIProfile;
|
||||
|
||||
devpriv->
|
||||
s_ModuleInfo
|
||||
[b_ModulNbr].
|
||||
s_SSICounterInfo.
|
||||
b_PositionTurnLength
|
||||
=
|
||||
b_PositionTurnLength;
|
||||
|
||||
devpriv->
|
||||
s_ModuleInfo
|
||||
[b_ModulNbr].
|
||||
s_SSICounterInfo.
|
||||
b_TurnCptLength
|
||||
=
|
||||
b_TurnCptLength;
|
||||
|
||||
/*********************************/
|
||||
/* Initialise the profile length */
|
||||
/*********************************/
|
||||
|
||||
if (b_SSICountingMode == APCI1710_BINARY_MODE) {
|
||||
|
||||
outl(b_SSIProfile + 1, devpriv->s_BoardInfos.ui_Address + 4 + (64 * b_ModulNbr));
|
||||
} else {
|
||||
|
||||
outl(b_SSIProfile, devpriv->s_BoardInfos.ui_Address + 4 + (64 * b_ModulNbr));
|
||||
}
|
||||
|
||||
/******************************/
|
||||
/* Calculate the output clock */
|
||||
/******************************/
|
||||
|
||||
ui_TimerValue
|
||||
=
|
||||
(UINT)
|
||||
(
|
||||
((ULONG) (b_PCIInputClock) * 500000UL) / ul_SSIOutputClock);
|
||||
|
||||
/************************/
|
||||
/* Initialise the timer */
|
||||
/************************/
|
||||
|
||||
outl(ui_TimerValue, devpriv->s_BoardInfos.ui_Address + (64 * b_ModulNbr));
|
||||
|
||||
/********************************/
|
||||
/* Initialise the counting mode */
|
||||
/********************************/
|
||||
|
||||
outl(7 * b_SSICountingMode, devpriv->s_BoardInfos.ui_Address + 12 + (64 * b_ModulNbr));
|
||||
|
||||
devpriv->
|
||||
s_ModuleInfo
|
||||
[b_ModulNbr].
|
||||
s_SSICounterInfo.
|
||||
b_SSIInit
|
||||
=
|
||||
1;
|
||||
} else {
|
||||
/*****************************************************/
|
||||
/* The selected SSI counting mode parameter is wrong */
|
||||
/*****************************************************/
|
||||
|
||||
DPRINTK("The selected SSI counting mode parameter is wrong\n");
|
||||
i_ReturnValue
|
||||
=
|
||||
-9;
|
||||
}
|
||||
} else {
|
||||
/******************************************/
|
||||
/* The selected SSI output clock is wrong */
|
||||
/******************************************/
|
||||
|
||||
DPRINTK("The selected SSI output clock is wrong\n");
|
||||
i_ReturnValue
|
||||
=
|
||||
-8;
|
||||
}
|
||||
} else {
|
||||
/*****************************************/
|
||||
/* The selected PCI input clock is wrong */
|
||||
/*****************************************/
|
||||
|
||||
DPRINTK("The selected PCI input clock is wrong\n");
|
||||
i_ReturnValue =
|
||||
-7;
|
||||
}
|
||||
} else {
|
||||
/********************************************/
|
||||
/* The selected SSI profile length is wrong */
|
||||
/********************************************/
|
||||
|
||||
DPRINTK("The selected SSI profile length is wrong\n");
|
||||
i_ReturnValue = -4;
|
||||
}
|
||||
} else {
|
||||
/******************************************************/
|
||||
/* The selected SSI turn counter data length is wrong */
|
||||
/******************************************************/
|
||||
|
||||
DPRINTK("The selected SSI turn counter data length is wrong\n");
|
||||
i_ReturnValue = -6;
|
||||
}
|
||||
} else {
|
||||
/**************************************************/
|
||||
/* The selected SSI position data length is wrong */
|
||||
/**************************************************/
|
||||
|
||||
DPRINTK("The selected SSI position data length is wrong\n");
|
||||
i_ReturnValue = -5;
|
||||
}
|
||||
} else {
|
||||
/********************************************/
|
||||
/* The selected SSI profile length is wrong */
|
||||
/********************************************/
|
||||
|
||||
DPRINTK("The selected SSI profile length is wrong\n");
|
||||
i_ReturnValue = -4;
|
||||
}
|
||||
} else {
|
||||
/**********************************/
|
||||
/* The module is not a SSI module */
|
||||
/**********************************/
|
||||
|
||||
DPRINTK("The module is not a SSI module\n");
|
||||
i_ReturnValue = -3;
|
||||
}
|
||||
} else {
|
||||
/***********************/
|
||||
/* Module number error */
|
||||
/***********************/
|
||||
|
||||
DPRINTK("Module number error\n");
|
||||
i_ReturnValue = -2;
|
||||
}
|
||||
|
||||
return (i_ReturnValue);
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : _INT_ i_APCI1710_Read1SSIValue |
|
||||
| (BYTE_ b_BoardHandle, |
|
||||
| BYTE_ b_ModulNbr, |
|
||||
| BYTE_ b_SelectedSSI, |
|
||||
| PULONG_ pul_Position, |
|
||||
| PULONG_ pul_TurnCpt)
|
||||
INT i_APCI1710_ReadSSIValue(struct comedi_device *dev,struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task :
|
||||
|
||||
|
||||
Read the selected SSI counter (b_SelectedSSI) from |
|
||||
| selected module (b_ModulNbr).
|
||||
or Read all SSI counter (b_SelectedSSI) from |
|
||||
| selected module (b_ModulNbr). |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|
|
||||
| BYTE_ b_ModulNbr : Module number to |
|
||||
| configure (0 to 3) |
|
||||
| BYTE_ b_SelectedSSI : Selection from SSI |
|
||||
| counter (0 to 2)
|
||||
|
||||
b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
|
||||
b_SelectedSSI = (BYTE) CR_CHAN(insn->chanspec); (in case of single ssi)
|
||||
b_ReadType = (BYTE) CR_RANGE(insn->chanspec);
|
||||
|
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : PULONG_ pul_Position : SSI position in the turn |
|
||||
| PULONG_ pul_TurnCpt : Number of turns
|
||||
|
||||
pul_Position = (PULONG) &data[0];
|
||||
pul_TurnCpt = (PULONG) &data[1]; |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : 0: No error |
|
||||
| -1: The handle parameter of the board is wrong |
|
||||
| -2: The module parameter is wrong |
|
||||
| -3: The module is not a SSI module |
|
||||
| -4: SSI not initialised see function |
|
||||
| "i_APCI1710_InitSSI" |
|
||||
| -5: The selected SSI is wrong |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
INT i_APCI1710_InsnReadSSIValue(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
INT i_ReturnValue = 0;
|
||||
BYTE b_Cpt;
|
||||
BYTE b_Length;
|
||||
BYTE b_Schift;
|
||||
BYTE b_SSICpt;
|
||||
DWORD dw_And;
|
||||
DWORD dw_And1;
|
||||
DWORD dw_And2;
|
||||
DWORD dw_StatusReg;
|
||||
DWORD dw_CounterValue;
|
||||
BYTE b_ModulNbr;
|
||||
BYTE b_SelectedSSI;
|
||||
BYTE b_ReadType;
|
||||
PULONG pul_Position;
|
||||
PULONG pul_TurnCpt;
|
||||
PULONG pul_Position1;
|
||||
PULONG pul_TurnCpt1;
|
||||
|
||||
i_ReturnValue = insn->n;
|
||||
pul_Position1 = (PULONG) & data[0];
|
||||
// For Read1
|
||||
pul_TurnCpt1 = (PULONG) & data[1];
|
||||
// For Read all
|
||||
pul_Position = (PULONG) & data[0]; //0-2
|
||||
pul_TurnCpt = (PULONG) & data[3]; //3-5
|
||||
b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
|
||||
b_SelectedSSI = (BYTE) CR_CHAN(insn->chanspec);
|
||||
b_ReadType = (BYTE) CR_RANGE(insn->chanspec);
|
||||
|
||||
/**************************/
|
||||
/* Test the module number */
|
||||
/**************************/
|
||||
|
||||
if (b_ModulNbr < 4) {
|
||||
/***********************/
|
||||
/* Test if SSI counter */
|
||||
/***********************/
|
||||
|
||||
if ((devpriv->s_BoardInfos.
|
||||
dw_MolduleConfiguration[b_ModulNbr] &
|
||||
0xFFFF0000UL) == APCI1710_SSI_COUNTER) {
|
||||
/***************************/
|
||||
/* Test if SSI initialised */
|
||||
/***************************/
|
||||
|
||||
if (devpriv->s_ModuleInfo[b_ModulNbr].
|
||||
s_SSICounterInfo.b_SSIInit == 1) {
|
||||
|
||||
switch (b_ReadType) {
|
||||
|
||||
case APCI1710_SSI_READ1VALUE:
|
||||
/****************************************/
|
||||
/* Test the selected SSI counter number */
|
||||
/****************************************/
|
||||
|
||||
if (b_SelectedSSI < 3) {
|
||||
/************************/
|
||||
/* Start the conversion */
|
||||
/************************/
|
||||
|
||||
outl(0, devpriv->s_BoardInfos.
|
||||
ui_Address + 8 +
|
||||
(64 * b_ModulNbr));
|
||||
|
||||
do {
|
||||
/*******************/
|
||||
/* Read the status */
|
||||
/*******************/
|
||||
|
||||
dw_StatusReg =
|
||||
inl(devpriv->
|
||||
s_BoardInfos.
|
||||
ui_Address +
|
||||
(64 * b_ModulNbr));
|
||||
}
|
||||
while ((dw_StatusReg & 0x1) !=
|
||||
0);
|
||||
|
||||
/******************************/
|
||||
/* Read the SSI counter value */
|
||||
/******************************/
|
||||
|
||||
dw_CounterValue =
|
||||
inl(devpriv->
|
||||
s_BoardInfos.
|
||||
ui_Address + 4 +
|
||||
(b_SelectedSSI * 4) +
|
||||
(64 * b_ModulNbr));
|
||||
|
||||
b_Length =
|
||||
devpriv->
|
||||
s_ModuleInfo
|
||||
[b_ModulNbr].
|
||||
s_SSICounterInfo.
|
||||
b_SSIProfile / 2;
|
||||
|
||||
if ((b_Length * 2) !=
|
||||
devpriv->
|
||||
s_ModuleInfo
|
||||
[b_ModulNbr].
|
||||
s_SSICounterInfo.
|
||||
b_SSIProfile) {
|
||||
b_Length++;
|
||||
}
|
||||
|
||||
b_Schift =
|
||||
b_Length -
|
||||
devpriv->
|
||||
s_ModuleInfo
|
||||
[b_ModulNbr].
|
||||
s_SSICounterInfo.
|
||||
b_PositionTurnLength;
|
||||
|
||||
*pul_Position1 =
|
||||
dw_CounterValue >>
|
||||
b_Schift;
|
||||
|
||||
dw_And = 1;
|
||||
|
||||
for (b_Cpt = 0;
|
||||
b_Cpt <
|
||||
devpriv->
|
||||
s_ModuleInfo
|
||||
[b_ModulNbr].
|
||||
s_SSICounterInfo.
|
||||
b_PositionTurnLength;
|
||||
b_Cpt++) {
|
||||
dw_And = dw_And * 2;
|
||||
}
|
||||
|
||||
*pul_Position1 =
|
||||
*pul_Position1 &
|
||||
((dw_And) - 1);
|
||||
|
||||
*pul_TurnCpt1 =
|
||||
dw_CounterValue >>
|
||||
b_Length;
|
||||
|
||||
dw_And = 1;
|
||||
|
||||
for (b_Cpt = 0;
|
||||
b_Cpt <
|
||||
devpriv->
|
||||
s_ModuleInfo
|
||||
[b_ModulNbr].
|
||||
s_SSICounterInfo.
|
||||
b_TurnCptLength;
|
||||
b_Cpt++) {
|
||||
dw_And = dw_And * 2;
|
||||
}
|
||||
|
||||
*pul_TurnCpt1 =
|
||||
*pul_TurnCpt1 &
|
||||
((dw_And) - 1);
|
||||
} else {
|
||||
/*****************************/
|
||||
/* The selected SSI is wrong */
|
||||
/*****************************/
|
||||
|
||||
DPRINTK("The selected SSI is wrong\n");
|
||||
i_ReturnValue = -5;
|
||||
}
|
||||
break;
|
||||
|
||||
case APCI1710_SSI_READALLVALUE:
|
||||
dw_And1 = 1;
|
||||
|
||||
for (b_Cpt = 0;
|
||||
b_Cpt <
|
||||
devpriv->
|
||||
s_ModuleInfo[b_ModulNbr].
|
||||
s_SSICounterInfo.
|
||||
b_PositionTurnLength; b_Cpt++) {
|
||||
dw_And1 = dw_And1 * 2;
|
||||
}
|
||||
|
||||
dw_And2 = 1;
|
||||
|
||||
for (b_Cpt = 0;
|
||||
b_Cpt <
|
||||
devpriv->
|
||||
s_ModuleInfo[b_ModulNbr].
|
||||
s_SSICounterInfo.
|
||||
b_TurnCptLength; b_Cpt++) {
|
||||
dw_And2 = dw_And2 * 2;
|
||||
}
|
||||
|
||||
/************************/
|
||||
/* Start the conversion */
|
||||
/************************/
|
||||
|
||||
outl(0, devpriv->s_BoardInfos.
|
||||
ui_Address + 8 +
|
||||
(64 * b_ModulNbr));
|
||||
|
||||
do {
|
||||
/*******************/
|
||||
/* Read the status */
|
||||
/*******************/
|
||||
|
||||
dw_StatusReg =
|
||||
inl(devpriv->
|
||||
s_BoardInfos.
|
||||
ui_Address +
|
||||
(64 * b_ModulNbr));
|
||||
}
|
||||
while ((dw_StatusReg & 0x1) != 0);
|
||||
|
||||
for (b_SSICpt = 0; b_SSICpt < 3;
|
||||
b_SSICpt++) {
|
||||
/******************************/
|
||||
/* Read the SSI counter value */
|
||||
/******************************/
|
||||
|
||||
dw_CounterValue =
|
||||
inl(devpriv->
|
||||
s_BoardInfos.
|
||||
ui_Address + 4 +
|
||||
(b_SSICpt * 4) +
|
||||
(64 * b_ModulNbr));
|
||||
|
||||
b_Length =
|
||||
devpriv->
|
||||
s_ModuleInfo
|
||||
[b_ModulNbr].
|
||||
s_SSICounterInfo.
|
||||
b_SSIProfile / 2;
|
||||
|
||||
if ((b_Length * 2) !=
|
||||
devpriv->
|
||||
s_ModuleInfo
|
||||
[b_ModulNbr].
|
||||
s_SSICounterInfo.
|
||||
b_SSIProfile) {
|
||||
b_Length++;
|
||||
}
|
||||
|
||||
b_Schift =
|
||||
b_Length -
|
||||
devpriv->
|
||||
s_ModuleInfo
|
||||
[b_ModulNbr].
|
||||
s_SSICounterInfo.
|
||||
b_PositionTurnLength;
|
||||
|
||||
pul_Position[b_SSICpt] =
|
||||
dw_CounterValue >>
|
||||
b_Schift;
|
||||
pul_Position[b_SSICpt] =
|
||||
pul_Position[b_SSICpt] &
|
||||
((dw_And1) - 1);
|
||||
|
||||
pul_TurnCpt[b_SSICpt] =
|
||||
dw_CounterValue >>
|
||||
b_Length;
|
||||
pul_TurnCpt[b_SSICpt] =
|
||||
pul_TurnCpt[b_SSICpt] &
|
||||
((dw_And2) - 1);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
printk("Read Type Inputs Wrong\n");
|
||||
|
||||
} // switch ending
|
||||
|
||||
} else {
|
||||
/***********************/
|
||||
/* SSI not initialised */
|
||||
/***********************/
|
||||
|
||||
DPRINTK("SSI not initialised\n");
|
||||
i_ReturnValue = -4;
|
||||
}
|
||||
} else {
|
||||
/**********************************/
|
||||
/* The module is not a SSI module */
|
||||
/**********************************/
|
||||
|
||||
DPRINTK("The module is not a SSI module\n");
|
||||
i_ReturnValue = -3;
|
||||
|
||||
}
|
||||
} else {
|
||||
/***********************/
|
||||
/* Module number error */
|
||||
/***********************/
|
||||
|
||||
DPRINTK("Module number error\n");
|
||||
i_ReturnValue = -2;
|
||||
}
|
||||
|
||||
return (i_ReturnValue);
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : _INT_ i_APCI1710_ReadSSI1DigitalInput |
|
||||
| (BYTE_ b_BoardHandle, |
|
||||
| BYTE_ b_ModulNbr, |
|
||||
| BYTE_ b_InputChannel, |
|
||||
| PBYTE_ pb_ChannelStatus) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task :
|
||||
(0) Set the digital output from selected SSI moule |
|
||||
| (b_ModuleNbr) ON
|
||||
(1) Set the digital output from selected SSI moule |
|
||||
| (b_ModuleNbr) OFF
|
||||
(2)Read the status from selected SSI digital input |
|
||||
| (b_InputChannel)
|
||||
(3)Read the status from all SSI digital inputs from |
|
||||
| selected SSI module (b_ModulNbr) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|
|
||||
| BYTE_ b_ModulNbr CR_AREF : Module number to |
|
||||
| configure (0 to 3) |
|
||||
| BYTE_ b_InputChannel CR_CHAN : Selection from digital |
|
||||
| data[0] which IOTYPE input ( 0 to 2) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : PBYTE_ pb_ChannelStatus : Digital input channel |
|
||||
| data[0] status |
|
||||
| 0 : Channle is not active|
|
||||
| 1 : Channle is active |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : 0: No error |
|
||||
| -1: The handle parameter of the board is wrong |
|
||||
| -2: The module parameter is wrong |
|
||||
| -3: The module is not a SSI module |
|
||||
| -4: The selected SSI digital input is wrong |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
INT i_APCI1710_InsnBitsSSIDigitalIO(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
INT i_ReturnValue = 0;
|
||||
DWORD dw_StatusReg;
|
||||
BYTE b_ModulNbr;
|
||||
BYTE b_InputChannel;
|
||||
PBYTE pb_ChannelStatus;
|
||||
PBYTE pb_InputStatus;
|
||||
BYTE b_IOType;
|
||||
i_ReturnValue = insn->n;
|
||||
b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
|
||||
b_IOType = (BYTE) data[0];
|
||||
|
||||
/**************************/
|
||||
/* Test the module number */
|
||||
/**************************/
|
||||
|
||||
if (b_ModulNbr < 4) {
|
||||
/***********************/
|
||||
/* Test if SSI counter */
|
||||
/***********************/
|
||||
|
||||
if ((devpriv->s_BoardInfos.
|
||||
dw_MolduleConfiguration[b_ModulNbr] &
|
||||
0xFFFF0000UL) == APCI1710_SSI_COUNTER) {
|
||||
switch (b_IOType) {
|
||||
case APCI1710_SSI_SET_CHANNELON:
|
||||
/*****************************/
|
||||
/* Set the digital output ON */
|
||||
/*****************************/
|
||||
|
||||
outl(1, devpriv->s_BoardInfos.ui_Address + 16 +
|
||||
(64 * b_ModulNbr));
|
||||
break;
|
||||
|
||||
case APCI1710_SSI_SET_CHANNELOFF:
|
||||
/******************************/
|
||||
/* Set the digital output OFF */
|
||||
/******************************/
|
||||
|
||||
outl(0, devpriv->s_BoardInfos.ui_Address + 16 +
|
||||
(64 * b_ModulNbr));
|
||||
break;
|
||||
|
||||
case APCI1710_SSI_READ_1CHANNEL:
|
||||
/******************************************/
|
||||
/* Test the digital imnput channel number */
|
||||
/******************************************/
|
||||
|
||||
b_InputChannel = (BYTE) CR_CHAN(insn->chanspec);
|
||||
pb_ChannelStatus = (PBYTE) & data[0];
|
||||
|
||||
if (b_InputChannel <= 2) {
|
||||
/**************************/
|
||||
/* Read all digital input */
|
||||
/**************************/
|
||||
|
||||
dw_StatusReg =
|
||||
inl(devpriv->s_BoardInfos.
|
||||
ui_Address + (64 * b_ModulNbr));
|
||||
*pb_ChannelStatus =
|
||||
(BYTE) (((~dw_StatusReg) >> (4 +
|
||||
b_InputChannel))
|
||||
& 1);
|
||||
} else {
|
||||
/********************************/
|
||||
/* Selected digital input error */
|
||||
/********************************/
|
||||
|
||||
DPRINTK("Selected digital input error\n");
|
||||
i_ReturnValue = -4;
|
||||
}
|
||||
break;
|
||||
|
||||
case APCI1710_SSI_READ_ALLCHANNEL:
|
||||
/**************************/
|
||||
/* Read all digital input */
|
||||
/**************************/
|
||||
pb_InputStatus = (PBYTE) & data[0];
|
||||
|
||||
dw_StatusReg =
|
||||
inl(devpriv->s_BoardInfos.ui_Address +
|
||||
(64 * b_ModulNbr));
|
||||
*pb_InputStatus =
|
||||
(BYTE) (((~dw_StatusReg) >> 4) & 7);
|
||||
break;
|
||||
|
||||
default:
|
||||
printk("IO type wrong\n");
|
||||
|
||||
} //switch end
|
||||
} else {
|
||||
/**********************************/
|
||||
/* The module is not a SSI module */
|
||||
/**********************************/
|
||||
|
||||
DPRINTK("The module is not a SSI module\n");
|
||||
i_ReturnValue = -3;
|
||||
}
|
||||
} else {
|
||||
/***********************/
|
||||
/* Module number error */
|
||||
/***********************/
|
||||
|
||||
DPRINTK("Module number error\n");
|
||||
i_ReturnValue = -2;
|
||||
}
|
||||
|
||||
return (i_ReturnValue);
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
*
|
||||
* ADDI-DATA GmbH
|
||||
* Dieselstrasse 3
|
||||
* D-77833 Ottersweier
|
||||
* Tel: +19(0)7223/9493-0
|
||||
* Fax: +49(0)7223/9493-92
|
||||
* http://www.addi-data-com
|
||||
* info@addi-data.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*/
|
||||
|
||||
#define APCI1710_30MHZ 30
|
||||
#define APCI1710_33MHZ 33
|
||||
#define APCI1710_40MHZ 40
|
||||
|
||||
#define APCI1710_BINARY_MODE 0x1
|
||||
#define APCI1710_GRAY_MODE 0x0
|
||||
|
||||
#define APCI1710_SSI_READ1VALUE 1
|
||||
#define APCI1710_SSI_READALLVALUE 2
|
||||
|
||||
#define APCI1710_SSI_SET_CHANNELON 0
|
||||
#define APCI1710_SSI_SET_CHANNELOFF 1
|
||||
#define APCI1710_SSI_READ_1CHANNEL 2
|
||||
#define APCI1710_SSI_READ_ALLCHANNEL 3
|
||||
|
||||
/*
|
||||
* SSI INISIALISATION FUNCTION
|
||||
*/
|
||||
INT i_APCI1710_InsnConfigInitSSI(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
INT i_APCI1710_InsnReadSSIValue(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
INT i_APCI1710_InsnBitsSSIDigitalIO(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
*
|
||||
* ADDI-DATA GmbH
|
||||
* Dieselstrasse 3
|
||||
* D-77833 Ottersweier
|
||||
* Tel: +19(0)7223/9493-0
|
||||
* Fax: +49(0)7223/9493-92
|
||||
* http://www.addi-data-com
|
||||
* info@addi-data.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*/
|
||||
|
||||
#define APCI1710_30MHZ 30
|
||||
#define APCI1710_33MHZ 33
|
||||
#define APCI1710_40MHZ 40
|
||||
|
||||
#define APCI1710_GATE_INPUT 10
|
||||
|
||||
#define APCI1710_TOR_SIMPLE_MODE 2
|
||||
#define APCI1710_TOR_DOUBLE_MODE 3
|
||||
#define APCI1710_TOR_QUADRUPLE_MODE 4
|
||||
|
||||
#define APCI1710_SINGLE 0
|
||||
#define APCI1710_CONTINUOUS 1
|
||||
|
||||
#define APCI1710_TOR_GETPROGRESSSTATUS 0
|
||||
#define APCI1710_TOR_GETCOUNTERVALUE 1
|
||||
#define APCI1710_TOR_READINTERRUPT 2
|
||||
|
||||
/*
|
||||
* TOR_COUNTER INISIALISATION FUNCTION
|
||||
*/
|
||||
INT i_APCI1710_InsnConfigInitTorCounter(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
INT i_APCI1710_InsnWriteEnableDisableTorCounter(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
|
||||
INT i_APCI1710_InsnReadGetTorCounterInitialisation(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
/*
|
||||
* TOR_COUNTER READ FUNCTION
|
||||
*/
|
||||
INT i_APCI1710_InsnBitsGetTorCounterProgressStatusAndValue(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
*
|
||||
* ADDI-DATA GmbH
|
||||
* Dieselstrasse 3
|
||||
* D-77833 Ottersweier
|
||||
* Tel: +19(0)7223/9493-0
|
||||
* Fax: +49(0)7223/9493-92
|
||||
* http://www.addi-data-com
|
||||
* info@addi-data.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*/
|
||||
|
||||
#define APCI1710_TTL_INIT 0
|
||||
#define APCI1710_TTL_INITDIRECTION 1
|
||||
|
||||
#define APCI1710_TTL_READCHANNEL 0
|
||||
#define APCI1710_TTL_READPORT 1
|
||||
|
||||
/*
|
||||
* TTL INISIALISATION FUNCTION
|
||||
*/
|
||||
INT i_APCI1710_InsnConfigInitTTLIO(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
/*
|
||||
* TTL INPUT FUNCTION
|
||||
*/
|
||||
INT i_APCI1710_InsnBitsReadTTLIO(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
INT i_APCI1710_InsnReadTTLIOAllPortValue(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
/*
|
||||
* TTL OUTPUT FUNCTIONS
|
||||
*/
|
||||
INT i_APCI1710_InsnWriteSetTTLIOChlOnOff(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
|
@ -0,0 +1,203 @@
|
|||
/**
|
||||
@verbatim
|
||||
|
||||
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
|
||||
ADDI-DATA GmbH
|
||||
Dieselstrasse 3
|
||||
D-77833 Ottersweier
|
||||
Tel: +19(0)7223/9493-0
|
||||
Fax: +49(0)7223/9493-92
|
||||
http://www.addi-data-com
|
||||
info@addi-data.com
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
You shoud also find the complete GPL in the COPYING file accompanying this source code.
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
/*
|
||||
+-----------------------------------------------------------------------+
|
||||
| (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
|
||||
+-----------------------------------------------------------------------+
|
||||
| Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
|
||||
| Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
|
||||
+-------------------------------+---------------------------------------+
|
||||
| Project : ADDI HEADER READ WRITER | Compiler : Visual C++ |
|
||||
| Module name : S5920.cpp | Version : 6.0 |
|
||||
+-------------------------------+---------------------------------------+
|
||||
| Author : E. LIBS Date : 02/05/2002 |
|
||||
+-----------------------------------------------------------------------+
|
||||
| Description : DLL with the S5920 PCI Controller functions |
|
||||
+-----------------------------------------------------------------------+
|
||||
| UPDATE'S |
|
||||
+-----------------------------------------------------------------------+
|
||||
| Date | Author | Description of updates |
|
||||
+----------+-----------+------------------------------------------------+
|
||||
| 28/08/02 | LIBS Eric | Add return codes each time a function of the |
|
||||
| | | Addi Library is called |
|
||||
+-----------------------------------------------------------------------+
|
||||
| 31/07/03 | KRAUTH J. | Changes for the MSX-Box |
|
||||
+-----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include "addi_amcc_S5920.h"
|
||||
|
||||
/*+----------------------------------------------------------------------------+*/
|
||||
/*| Function Name : INT i_AddiHeaderRW_ReadEeprom |*/
|
||||
/*| (INT i_NbOfWordsToRead, |*/
|
||||
/*| DWORD dw_PCIBoardEepromAddress, |*/
|
||||
/*| WORD w_EepromStartAddress, |*/
|
||||
/*| PWORD pw_DataRead) |*/
|
||||
/*+----------------------------------------------------------------------------+*/
|
||||
/*| Task : Read word from the 5920 eeprom. |*/
|
||||
/*+----------------------------------------------------------------------------+*/
|
||||
/*| Input Parameters : INT i_NbOfWordsToRead : Nbr. of word to read |*/
|
||||
/*| DWORD dw_PCIBoardEepromAddress : Address of the eeprom |*/
|
||||
/*| WORD w_EepromStartAddress : Eeprom strat address |*/
|
||||
/*+----------------------------------------------------------------------------+*/
|
||||
/*| Output Parameters : PWORD pw_DataRead : Read data |*/
|
||||
/*+----------------------------------------------------------------------------+*/
|
||||
/*| Return Value : - |*/
|
||||
/*+----------------------------------------------------------------------------+*/
|
||||
|
||||
INT i_AddiHeaderRW_ReadEeprom(INT i_NbOfWordsToRead,
|
||||
DWORD dw_PCIBoardEepromAddress,
|
||||
WORD w_EepromStartAddress, PWORD pw_DataRead)
|
||||
{
|
||||
DWORD dw_eeprom_busy = 0;
|
||||
INT i_Counter = 0;
|
||||
INT i_WordCounter;
|
||||
INT i;
|
||||
BYTE pb_ReadByte[1];
|
||||
BYTE b_ReadLowByte = 0;
|
||||
BYTE b_ReadHighByte = 0;
|
||||
BYTE b_SelectedAddressLow = 0;
|
||||
BYTE b_SelectedAddressHigh = 0;
|
||||
WORD w_ReadWord = 0;
|
||||
|
||||
for (i_WordCounter = 0; i_WordCounter < i_NbOfWordsToRead;
|
||||
i_WordCounter++) {
|
||||
do {
|
||||
dw_eeprom_busy =
|
||||
inl(dw_PCIBoardEepromAddress +
|
||||
AMCC_OP_REG_MCSR);
|
||||
dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
|
||||
}
|
||||
while (dw_eeprom_busy == EEPROM_BUSY);
|
||||
|
||||
for (i_Counter = 0; i_Counter < 2; i_Counter++) {
|
||||
b_SelectedAddressLow = (w_EepromStartAddress + i_Counter) % 256; //Read the low 8 bit part
|
||||
b_SelectedAddressHigh = (w_EepromStartAddress + i_Counter) / 256; //Read the high 8 bit part
|
||||
|
||||
//Select the load low address mode
|
||||
outb(NVCMD_LOAD_LOW,
|
||||
dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
|
||||
3);
|
||||
|
||||
//Wait on busy
|
||||
do {
|
||||
dw_eeprom_busy =
|
||||
inl(dw_PCIBoardEepromAddress +
|
||||
AMCC_OP_REG_MCSR);
|
||||
dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
|
||||
}
|
||||
while (dw_eeprom_busy == EEPROM_BUSY);
|
||||
|
||||
//Load the low address
|
||||
outb(b_SelectedAddressLow,
|
||||
dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
|
||||
2);
|
||||
|
||||
//Wait on busy
|
||||
do {
|
||||
dw_eeprom_busy =
|
||||
inl(dw_PCIBoardEepromAddress +
|
||||
AMCC_OP_REG_MCSR);
|
||||
dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
|
||||
}
|
||||
while (dw_eeprom_busy == EEPROM_BUSY);
|
||||
|
||||
//Select the load high address mode
|
||||
outb(NVCMD_LOAD_HIGH,
|
||||
dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
|
||||
3);
|
||||
|
||||
//Wait on busy
|
||||
do {
|
||||
dw_eeprom_busy =
|
||||
inl(dw_PCIBoardEepromAddress +
|
||||
AMCC_OP_REG_MCSR);
|
||||
dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
|
||||
}
|
||||
while (dw_eeprom_busy == EEPROM_BUSY);
|
||||
|
||||
//Load the high address
|
||||
outb(b_SelectedAddressHigh,
|
||||
dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
|
||||
2);
|
||||
|
||||
//Wait on busy
|
||||
do {
|
||||
dw_eeprom_busy =
|
||||
inl(dw_PCIBoardEepromAddress +
|
||||
AMCC_OP_REG_MCSR);
|
||||
dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
|
||||
}
|
||||
while (dw_eeprom_busy == EEPROM_BUSY);
|
||||
|
||||
//Select the READ mode
|
||||
outb(NVCMD_BEGIN_READ,
|
||||
dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
|
||||
3);
|
||||
|
||||
//Wait on busy
|
||||
do {
|
||||
dw_eeprom_busy =
|
||||
inl(dw_PCIBoardEepromAddress +
|
||||
AMCC_OP_REG_MCSR);
|
||||
dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
|
||||
}
|
||||
while (dw_eeprom_busy == EEPROM_BUSY);
|
||||
|
||||
//Read data into the EEPROM
|
||||
*pb_ReadByte =
|
||||
inb(dw_PCIBoardEepromAddress +
|
||||
AMCC_OP_REG_MCSR + 2);
|
||||
|
||||
//Wait on busy
|
||||
do {
|
||||
dw_eeprom_busy =
|
||||
inl(dw_PCIBoardEepromAddress +
|
||||
AMCC_OP_REG_MCSR);
|
||||
dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
|
||||
}
|
||||
while (dw_eeprom_busy == EEPROM_BUSY);
|
||||
|
||||
//Select the upper address part
|
||||
if (i_Counter == 0) {
|
||||
b_ReadLowByte = pb_ReadByte[0];
|
||||
} else {
|
||||
b_ReadHighByte = pb_ReadByte[0];
|
||||
}
|
||||
|
||||
//Sleep
|
||||
for (i = 0; i < 10000; i++) ;
|
||||
|
||||
}
|
||||
w_ReadWord =
|
||||
(b_ReadLowByte | (((unsigned short)b_ReadHighByte) *
|
||||
256));
|
||||
|
||||
pw_DataRead[i_WordCounter] = w_ReadWord;
|
||||
|
||||
w_EepromStartAddress += 2; // to read the next word
|
||||
|
||||
} // for (...) i_NbOfWordsToRead
|
||||
return (0);
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
*
|
||||
* ADDI-DATA GmbH
|
||||
* Dieselstrasse 3
|
||||
* D-77833 Ottersweier
|
||||
* Tel: +19(0)7223/9493-0
|
||||
* Fax: +49(0)7223/9493-92
|
||||
* http://www.addi-data-com
|
||||
* info@addi-data.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*/
|
||||
|
||||
#define AMCC_OP_REG_MCSR 0x3c
|
||||
#define EEPROM_BUSY 0x80000000
|
||||
#define NVCMD_LOAD_LOW (0x4 << 5) /* nvRam load low command */
|
||||
#define NVCMD_LOAD_HIGH (0x5 << 5) /* nvRam load high command */
|
||||
#define NVCMD_BEGIN_READ (0x7 << 5) /* nvRam begin read command */
|
||||
#define NVCMD_BEGIN_WRITE (0x6 << 5) /* EEPROM begin write command */
|
||||
|
||||
INT i_AddiHeaderRW_ReadEeprom(INT i_NbOfWordsToRead,
|
||||
DWORD dw_PCIBoardEepromAddress,
|
||||
WORD w_EepromStartAddress, PWORD pw_DataRead);
|
|
@ -0,0 +1,476 @@
|
|||
/*
|
||||
* Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
*
|
||||
* ADDI-DATA GmbH
|
||||
* Dieselstrasse 3
|
||||
* D-77833 Ottersweier
|
||||
* Tel: +19(0)7223/9493-0
|
||||
* Fax: +49(0)7223/9493-92
|
||||
* http://www.addi-data-com
|
||||
* info@addi-data.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*/
|
||||
|
||||
/* Header file for AMCC s 5933 */
|
||||
|
||||
#ifndef _AMCC_S5933_H_
|
||||
#define _AMCC_S5933_H_
|
||||
|
||||
#include "../../comedidev.h"
|
||||
|
||||
#include "../comedi_pci.h"
|
||||
|
||||
#ifdef PCI_SUPPORT_VER1
|
||||
#error No support for 2.1.55 and older
|
||||
#endif
|
||||
|
||||
/* written on base0 */
|
||||
#define FIFO_ADVANCE_ON_BYTE_2 0x20000000
|
||||
|
||||
/* added for step 6 dma written on base2 */
|
||||
#define AMWEN_ENABLE 0x02
|
||||
|
||||
#define A2P_FIFO_WRITE_ENABLE 0x01
|
||||
|
||||
/* for transfer count enable bit */
|
||||
#define AGCSTS_TC_ENABLE 0x10000000
|
||||
|
||||
/*
|
||||
* ADDON RELATED ADDITIONS
|
||||
*/
|
||||
/* Constant */
|
||||
#define APCI3120_ENABLE_TRANSFER_ADD_ON_LOW 0x00
|
||||
#define APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH 0x1200
|
||||
#define APCI3120_A2P_FIFO_MANAGEMENT 0x04000400L
|
||||
#define APCI3120_AMWEN_ENABLE 0x02
|
||||
#define APCI3120_A2P_FIFO_WRITE_ENABLE 0x01
|
||||
#define APCI3120_FIFO_ADVANCE_ON_BYTE_2 0x20000000L
|
||||
#define APCI3120_ENABLE_WRITE_TC_INT 0x00004000L
|
||||
#define APCI3120_CLEAR_WRITE_TC_INT 0x00040000L
|
||||
#define APCI3120_DISABLE_AMWEN_AND_A2P_FIFO_WRITE 0x0
|
||||
#define APCI3120_DISABLE_BUS_MASTER_ADD_ON 0x0
|
||||
#define APCI3120_DISABLE_BUS_MASTER_PCI 0x0
|
||||
|
||||
/* ADD_ON ::: this needed since apci supports 16 bit interface to add on */
|
||||
#define APCI3120_ADD_ON_AGCSTS_LOW 0x3C
|
||||
#define APCI3120_ADD_ON_AGCSTS_HIGH (APCI3120_ADD_ON_AGCSTS_LOW + 2)
|
||||
#define APCI3120_ADD_ON_MWAR_LOW 0x24
|
||||
#define APCI3120_ADD_ON_MWAR_HIGH (APCI3120_ADD_ON_MWAR_LOW + 2)
|
||||
#define APCI3120_ADD_ON_MWTC_LOW 0x058
|
||||
#define APCI3120_ADD_ON_MWTC_HIGH (APCI3120_ADD_ON_MWTC_LOW + 2)
|
||||
|
||||
/* AMCC */
|
||||
#define APCI3120_AMCC_OP_MCSR 0x3C
|
||||
#define APCI3120_AMCC_OP_REG_INTCSR 0x38
|
||||
|
||||
/*
|
||||
* AMCC Operation Register Offsets - PCI
|
||||
*/
|
||||
#define AMCC_OP_REG_OMB1 0x00
|
||||
#define AMCC_OP_REG_OMB2 0x04
|
||||
#define AMCC_OP_REG_OMB3 0x08
|
||||
#define AMCC_OP_REG_OMB4 0x0c
|
||||
#define AMCC_OP_REG_IMB1 0x10
|
||||
#define AMCC_OP_REG_IMB2 0x14
|
||||
#define AMCC_OP_REG_IMB3 0x18
|
||||
#define AMCC_OP_REG_IMB4 0x1c
|
||||
#define AMCC_OP_REG_FIFO 0x20
|
||||
#define AMCC_OP_REG_MWAR 0x24
|
||||
#define AMCC_OP_REG_MWTC 0x28
|
||||
#define AMCC_OP_REG_MRAR 0x2c
|
||||
#define AMCC_OP_REG_MRTC 0x30
|
||||
#define AMCC_OP_REG_MBEF 0x34
|
||||
#define AMCC_OP_REG_INTCSR 0x38
|
||||
/* INT source */
|
||||
#define AMCC_OP_REG_INTCSR_SRC (AMCC_OP_REG_INTCSR + 2)
|
||||
/* FIFO ctrl */
|
||||
#define AMCC_OP_REG_INTCSR_FEC (AMCC_OP_REG_INTCSR + 3)
|
||||
#define AMCC_OP_REG_MCSR 0x3c
|
||||
/* Data in byte 2 */
|
||||
#define AMCC_OP_REG_MCSR_NVDATA (AMCC_OP_REG_MCSR + 2)
|
||||
/* Command in byte 3 */
|
||||
#define AMCC_OP_REG_MCSR_NVCMD (AMCC_OP_REG_MCSR + 3)
|
||||
|
||||
#define AMCC_FIFO_DEPTH_DWORD 8
|
||||
#define AMCC_FIFO_DEPTH_BYTES (8 * sizeof(u32))
|
||||
|
||||
/*
|
||||
* AMCC Operation Registers Size - PCI
|
||||
*/
|
||||
#define AMCC_OP_REG_SIZE 64 /* in bytes */
|
||||
|
||||
/*
|
||||
* AMCC Operation Register Offsets - Add-on
|
||||
*/
|
||||
#define AMCC_OP_REG_AIMB1 0x00
|
||||
#define AMCC_OP_REG_AIMB2 0x04
|
||||
#define AMCC_OP_REG_AIMB3 0x08
|
||||
#define AMCC_OP_REG_AIMB4 0x0c
|
||||
#define AMCC_OP_REG_AOMB1 0x10
|
||||
#define AMCC_OP_REG_AOMB2 0x14
|
||||
#define AMCC_OP_REG_AOMB3 0x18
|
||||
#define AMCC_OP_REG_AOMB4 0x1c
|
||||
#define AMCC_OP_REG_AFIFO 0x20
|
||||
#define AMCC_OP_REG_AMWAR 0x24
|
||||
#define AMCC_OP_REG_APTA 0x28
|
||||
#define AMCC_OP_REG_APTD 0x2c
|
||||
#define AMCC_OP_REG_AMRAR 0x30
|
||||
#define AMCC_OP_REG_AMBEF 0x34
|
||||
#define AMCC_OP_REG_AINT 0x38
|
||||
#define AMCC_OP_REG_AGCSTS 0x3c
|
||||
#define AMCC_OP_REG_AMWTC 0x58
|
||||
#define AMCC_OP_REG_AMRTC 0x5c
|
||||
|
||||
/*
|
||||
* AMCC - Add-on General Control/Status Register
|
||||
*/
|
||||
#define AGCSTS_CONTROL_MASK 0xfffff000
|
||||
#define AGCSTS_NV_ACC_MASK 0xe0000000
|
||||
#define AGCSTS_RESET_MASK 0x0e000000
|
||||
#define AGCSTS_NV_DA_MASK 0x00ff0000
|
||||
#define AGCSTS_BIST_MASK 0x0000f000
|
||||
#define AGCSTS_STATUS_MASK 0x000000ff
|
||||
#define AGCSTS_TCZERO_MASK 0x000000c0
|
||||
#define AGCSTS_FIFO_ST_MASK 0x0000003f
|
||||
|
||||
#define AGCSTS_RESET_MBFLAGS 0x08000000
|
||||
#define AGCSTS_RESET_P2A_FIFO 0x04000000
|
||||
#define AGCSTS_RESET_A2P_FIFO 0x02000000
|
||||
#define AGCSTS_RESET_FIFOS (AGCSTS_RESET_A2P_FIFO | AGCSTS_RESET_P2A_FIFO)
|
||||
|
||||
#define AGCSTS_A2P_TCOUNT 0x00000080
|
||||
#define AGCSTS_P2A_TCOUNT 0x00000040
|
||||
|
||||
#define AGCSTS_FS_P2A_EMPTY 0x00000020
|
||||
#define AGCSTS_FS_P2A_HALF 0x00000010
|
||||
#define AGCSTS_FS_P2A_FULL 0x00000008
|
||||
|
||||
#define AGCSTS_FS_A2P_EMPTY 0x00000004
|
||||
#define AGCSTS_FS_A2P_HALF 0x00000002
|
||||
#define AGCSTS_FS_A2P_FULL 0x00000001
|
||||
|
||||
/*
|
||||
* AMCC - Add-on Interrupt Control/Status Register
|
||||
*/
|
||||
#define AINT_INT_MASK 0x00ff0000
|
||||
#define AINT_SEL_MASK 0x0000ffff
|
||||
#define AINT_IS_ENSEL_MASK 0x00001f1f
|
||||
|
||||
#define AINT_INT_ASSERTED 0x00800000
|
||||
#define AINT_BM_ERROR 0x00200000
|
||||
#define AINT_BIST_INT 0x00100000
|
||||
|
||||
#define AINT_RT_COMPLETE 0x00080000
|
||||
#define AINT_WT_COMPLETE 0x00040000
|
||||
|
||||
#define AINT_OUT_MB_INT 0x00020000
|
||||
#define AINT_IN_MB_INT 0x00010000
|
||||
|
||||
#define AINT_READ_COMPL 0x00008000
|
||||
#define AINT_WRITE_COMPL 0x00004000
|
||||
|
||||
#define AINT_OMB_ENABLE 0x00001000
|
||||
#define AINT_OMB_SELECT 0x00000c00
|
||||
#define AINT_OMB_BYTE 0x00000300
|
||||
|
||||
#define AINT_IMB_ENABLE 0x00000010
|
||||
#define AINT_IMB_SELECT 0x0000000c
|
||||
#define AINT_IMB_BYTE 0x00000003
|
||||
|
||||
/* Enable Bus Mastering */
|
||||
#define EN_A2P_TRANSFERS 0x00000400
|
||||
/* FIFO Flag Reset */
|
||||
#define RESET_A2P_FLAGS 0x04000000L
|
||||
/* FIFO Relative Priority */
|
||||
#define A2P_HI_PRIORITY 0x00000100L
|
||||
/* Identify Interrupt Sources */
|
||||
#define ANY_S593X_INT 0x00800000L
|
||||
#define READ_TC_INT 0x00080000L
|
||||
#define WRITE_TC_INT 0x00040000L
|
||||
#define IN_MB_INT 0x00020000L
|
||||
#define MASTER_ABORT_INT 0x00100000L
|
||||
#define TARGET_ABORT_INT 0x00200000L
|
||||
#define BUS_MASTER_INT 0x00200000L
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
struct pcilst_struct {
|
||||
struct pcilst_struct *next;
|
||||
int used;
|
||||
struct pci_dev *pcidev;
|
||||
unsigned short vendor;
|
||||
unsigned short device;
|
||||
unsigned char pci_bus;
|
||||
unsigned char pci_slot;
|
||||
unsigned char pci_func;
|
||||
resource_size_t io_addr[5];
|
||||
unsigned int irq;
|
||||
};
|
||||
|
||||
/* ptr to root list of all amcc devices */
|
||||
struct pcilst_struct *amcc_devices;
|
||||
|
||||
static const int i_ADDIDATADeviceID[] = { 0x15B8, 0x10E8 };
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
void v_pci_card_list_init(unsigned short pci_vendor, char display);
|
||||
void v_pci_card_list_cleanup(unsigned short pci_vendor);
|
||||
struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id,
|
||||
unsigned short
|
||||
device_id);
|
||||
int i_find_free_pci_card_by_position(unsigned short vendor_id,
|
||||
unsigned short device_id,
|
||||
unsigned short pci_bus,
|
||||
unsigned short pci_slot,
|
||||
struct pcilst_struct **card);
|
||||
struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id,
|
||||
unsigned short device_id,
|
||||
unsigned short pci_bus,
|
||||
unsigned short pci_slot,
|
||||
int i_Master);
|
||||
|
||||
int pci_card_alloc(struct pcilst_struct *amcc, int master);
|
||||
int i_pci_card_free(struct pcilst_struct *amcc);
|
||||
void v_pci_card_list_display(void);
|
||||
int i_pci_card_data(struct pcilst_struct *amcc,
|
||||
unsigned char *pci_bus, unsigned char *pci_slot,
|
||||
unsigned char *pci_func, resource_size_t * io_addr,
|
||||
unsigned int *irq);
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* build list of amcc cards in this system */
|
||||
void v_pci_card_list_init(unsigned short pci_vendor, char display)
|
||||
{
|
||||
struct pci_dev *pcidev;
|
||||
struct pcilst_struct *amcc, *last;
|
||||
int i;
|
||||
int i_Count = 0;
|
||||
amcc_devices = NULL;
|
||||
last = NULL;
|
||||
|
||||
for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
|
||||
pcidev != NULL;
|
||||
pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
|
||||
for (i_Count = 0; i_Count < 2; i_Count++) {
|
||||
pci_vendor = i_ADDIDATADeviceID[i_Count];
|
||||
if (pcidev->vendor == pci_vendor) {
|
||||
amcc = kmalloc(sizeof(*amcc), GFP_KERNEL);
|
||||
memset(amcc, 0, sizeof(*amcc));
|
||||
|
||||
amcc->pcidev = pcidev;
|
||||
if (last)
|
||||
last->next = amcc;
|
||||
else
|
||||
amcc_devices = amcc;
|
||||
last = amcc;
|
||||
|
||||
amcc->vendor = pcidev->vendor;
|
||||
amcc->device = pcidev->device;
|
||||
amcc->pci_bus = pcidev->bus->number;
|
||||
amcc->pci_slot = PCI_SLOT(pcidev->devfn);
|
||||
amcc->pci_func = PCI_FUNC(pcidev->devfn);
|
||||
/* Note: resources may be invalid if PCI device
|
||||
* not enabled, but they are corrected in
|
||||
* pci_card_alloc. */
|
||||
for (i = 0; i < 5; i++)
|
||||
amcc->io_addr[i] =
|
||||
pci_resource_start(pcidev, i);
|
||||
amcc->irq = pcidev->irq;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (display)
|
||||
v_pci_card_list_display();
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* free up list of amcc cards in this system */
|
||||
void v_pci_card_list_cleanup(unsigned short pci_vendor)
|
||||
{
|
||||
struct pcilst_struct *amcc, *next;
|
||||
|
||||
for (amcc = amcc_devices; amcc; amcc = next) {
|
||||
next = amcc->next;
|
||||
kfree(amcc);
|
||||
}
|
||||
|
||||
amcc_devices = NULL;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* find first unused card with this device_id */
|
||||
struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id,
|
||||
unsigned short device_id)
|
||||
{
|
||||
struct pcilst_struct *amcc, *next;
|
||||
|
||||
for (amcc = amcc_devices; amcc; amcc = next) {
|
||||
next = amcc->next;
|
||||
if ((!amcc->used) && (amcc->device == device_id)
|
||||
&& (amcc->vendor == vendor_id))
|
||||
return amcc;
|
||||
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* find card on requested position */
|
||||
int i_find_free_pci_card_by_position(unsigned short vendor_id,
|
||||
unsigned short device_id,
|
||||
unsigned short pci_bus,
|
||||
unsigned short pci_slot,
|
||||
struct pcilst_struct **card)
|
||||
{
|
||||
struct pcilst_struct *amcc, *next;
|
||||
|
||||
*card = NULL;
|
||||
for (amcc = amcc_devices; amcc; amcc = next) {
|
||||
next = amcc->next;
|
||||
if ((amcc->vendor == vendor_id) && (amcc->device == device_id)
|
||||
&& (amcc->pci_bus == pci_bus)
|
||||
&& (amcc->pci_slot == pci_slot)) {
|
||||
if (!(amcc->used)) {
|
||||
*card = amcc;
|
||||
return 0; /* ok, card is found */
|
||||
} else {
|
||||
rt_printk(" - \nCard on requested position is used b:s %d:%d!\n",
|
||||
pci_bus, pci_slot);
|
||||
return 2; /* card exist but is used */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* no card found */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* mark card as used */
|
||||
int pci_card_alloc(struct pcilst_struct *amcc, int master)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!amcc)
|
||||
return -1;
|
||||
|
||||
if (amcc->used)
|
||||
return 1;
|
||||
if (comedi_pci_enable(amcc->pcidev, "addi_amcc_s5933"))
|
||||
return -1;
|
||||
/* Resources will be accurate now. */
|
||||
for (i = 0; i < 5; i++)
|
||||
amcc->io_addr[i] = pci_resource_start(amcc->pcidev, i);
|
||||
if (master)
|
||||
pci_set_master(amcc->pcidev);
|
||||
amcc->used = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* mark card as free */
|
||||
int i_pci_card_free(struct pcilst_struct *amcc)
|
||||
{
|
||||
if (!amcc)
|
||||
return -1;
|
||||
|
||||
if (!amcc->used)
|
||||
return 1;
|
||||
amcc->used = 0;
|
||||
comedi_pci_disable(amcc->pcidev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* display list of found cards */
|
||||
void v_pci_card_list_display(void)
|
||||
{
|
||||
struct pcilst_struct *amcc, *next;
|
||||
|
||||
printk(KERN_DEBUG "List of pci cards\n");
|
||||
printk(KERN_DEBUG "bus:slot:func vendor device io_amcc io_daq irq used\n");
|
||||
|
||||
for (amcc = amcc_devices; amcc; amcc = next) {
|
||||
next = amcc->next;
|
||||
printk
|
||||
("%2d %2d %2d 0x%4x 0x%4x 0x%8llx 0x%8llx %2u %2d\n",
|
||||
amcc->pci_bus, amcc->pci_slot, amcc->pci_func,
|
||||
amcc->vendor, amcc->device,
|
||||
(unsigned long long)amcc->io_addr[0],
|
||||
(unsigned long long)amcc->io_addr[2], amcc->irq,
|
||||
amcc->used);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* return all card information for driver */
|
||||
int i_pci_card_data(struct pcilst_struct *amcc,
|
||||
unsigned char *pci_bus, unsigned char *pci_slot,
|
||||
unsigned char *pci_func, resource_size_t * io_addr,
|
||||
unsigned int *irq)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!amcc)
|
||||
return -1;
|
||||
*pci_bus = amcc->pci_bus;
|
||||
*pci_slot = amcc->pci_slot;
|
||||
*pci_func = amcc->pci_func;
|
||||
for (i = 0; i < 5; i++)
|
||||
io_addr[i] = amcc->io_addr[i];
|
||||
*irq = amcc->irq;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* select and alloc card */
|
||||
struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id,
|
||||
unsigned short device_id,
|
||||
unsigned short pci_bus,
|
||||
unsigned short pci_slot,
|
||||
int i_Master)
|
||||
{
|
||||
struct pcilst_struct *card;
|
||||
|
||||
if ((pci_bus < 1) & (pci_slot < 1)) {
|
||||
/* use autodetection */
|
||||
card = ptr_find_free_pci_card_by_device(vendor_id, device_id);
|
||||
if (card == NULL) {
|
||||
rt_printk(" - Unused card not found in system!\n");
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
switch (i_find_free_pci_card_by_position(vendor_id, device_id,
|
||||
pci_bus, pci_slot,
|
||||
&card)) {
|
||||
case 1:
|
||||
rt_printk(" - Card not found on requested position b:s %d:%d!\n",
|
||||
pci_bus, pci_slot);
|
||||
return NULL;
|
||||
case 2:
|
||||
rt_printk(" - Card on requested position is used b:s %d:%d!\n",
|
||||
pci_bus, pci_slot);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (pci_card_alloc(card, i_Master) != 0) {
|
||||
rt_printk(" - Can't allocate card!\n");
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
return card;
|
||||
}
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,462 @@
|
|||
/*
|
||||
* Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
*
|
||||
* ADDI-DATA GmbH
|
||||
* Dieselstrasse 3
|
||||
* D-77833 Ottersweier
|
||||
* Tel: +19(0)7223/9493-0
|
||||
* Fax: +49(0)7223/9493-92
|
||||
* http://www.addi-data-com
|
||||
* info@addi-data.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/timex.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kmod.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include "../../comedidev.h"
|
||||
#include "addi_amcc_s5933.h"
|
||||
|
||||
#define ERROR -1
|
||||
#define SUCCESS 1
|
||||
|
||||
/* variable type definition */
|
||||
typedef unsigned char BYTE, *PBYTE;
|
||||
typedef short SHORT, *PSHORT;
|
||||
typedef unsigned short USHORT, *PUSHORT;
|
||||
typedef unsigned short WORD, *PWORD;
|
||||
typedef int INT, *PINT;;
|
||||
typedef unsigned int UINT, *PUINT;
|
||||
typedef int LONG, *PLONG; /* 32-bit */
|
||||
typedef unsigned int ULONG, *PULONG; /* 32-bit */
|
||||
typedef unsigned int DWORD, *PDWORD; /* 32-bit */
|
||||
typedef unsigned long ULONG_PTR;
|
||||
|
||||
typedef const struct comedi_lrange *PCRANGE;
|
||||
|
||||
#define LOBYTE(W) (BYTE)((W) & 0xFF)
|
||||
#define HIBYTE(W) (BYTE)(((W) >> 8) & 0xFF)
|
||||
#define MAKEWORD(H, L) (USHORT)((L) | ((H) << 8))
|
||||
#define LOWORD(W) (USHORT)((W) & 0xFFFF)
|
||||
#define HIWORD(W) (USHORT)(((W) >> 16) & 0xFFFF)
|
||||
#define MAKEDWORD(H, L) (UINT)((L) | ((H) << 16))
|
||||
|
||||
#define ADDI_ENABLE 1
|
||||
#define ADDI_DISABLE 0
|
||||
#define APCI1710_SAVE_INTERRUPT 1
|
||||
|
||||
#define ADDIDATA_EEPROM 1
|
||||
#define ADDIDATA_NO_EEPROM 0
|
||||
#define ADDIDATA_93C76 "93C76"
|
||||
#define ADDIDATA_S5920 "S5920"
|
||||
#define ADDIDATA_S5933 "S5933"
|
||||
#define ADDIDATA_9054 "9054"
|
||||
|
||||
/* ADDIDATA Enable Disable */
|
||||
#define ADDIDATA_ENABLE 1
|
||||
#define ADDIDATA_DISABLE 0
|
||||
|
||||
/* Structures */
|
||||
|
||||
/* structure for the boardtype */
|
||||
typedef struct {
|
||||
const char *pc_DriverName; // driver name
|
||||
INT i_VendorId; //PCI vendor a device ID of card
|
||||
INT i_DeviceId;
|
||||
INT i_IorangeBase0;
|
||||
INT i_IorangeBase1;
|
||||
INT i_IorangeBase2; // base 2 range
|
||||
INT i_IorangeBase3; // base 3 range
|
||||
INT i_PCIEeprom; // eeprom present or not
|
||||
char *pc_EepromChip; // type of chip
|
||||
INT i_NbrAiChannel; // num of A/D chans
|
||||
INT i_NbrAiChannelDiff; // num of A/D chans in diff mode
|
||||
INT i_AiChannelList; // len of chanlist
|
||||
INT i_NbrAoChannel; // num of D/A chans
|
||||
INT i_AiMaxdata; // resolution of A/D
|
||||
INT i_AoMaxdata; // resolution of D/A
|
||||
PCRANGE pr_AiRangelist; // rangelist for A/D
|
||||
PCRANGE pr_AoRangelist; // rangelist for D/A
|
||||
|
||||
INT i_NbrDiChannel; // Number of DI channels
|
||||
INT i_NbrDoChannel; // Number of DO channels
|
||||
INT i_DoMaxdata; // data to set all chanels high
|
||||
|
||||
INT i_NbrTTLChannel; // Number of TTL channels
|
||||
PCRANGE pr_TTLRangelist; // rangelist for TTL
|
||||
|
||||
INT i_Dma; // dma present or not
|
||||
INT i_Timer; // timer subdevice present or not
|
||||
BYTE b_AvailableConvertUnit;
|
||||
UINT ui_MinAcquisitiontimeNs; // Minimum Acquisition in Nano secs
|
||||
UINT ui_MinDelaytimeNs; // Minimum Delay in Nano secs
|
||||
|
||||
/* interrupt and reset */
|
||||
void (*v_hwdrv_Interrupt)(int irq, void *d);
|
||||
int (*i_hwdrv_Reset)(struct comedi_device *dev);
|
||||
|
||||
/* Subdevice functions */
|
||||
|
||||
/* ANALOG INPUT */
|
||||
int (*i_hwdrv_InsnConfigAnalogInput)(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
int (*i_hwdrv_InsnReadAnalogInput)(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
int (*i_hwdrv_InsnWriteAnalogInput)(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
int (*i_hwdrv_InsnBitsAnalogInput)(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
int (*i_hwdrv_CommandTestAnalogInput)(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd);
|
||||
int (*i_hwdrv_CommandAnalogInput)(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s);
|
||||
int (*i_hwdrv_CancelAnalogInput)(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s);
|
||||
|
||||
/* Analog Output */
|
||||
int (*i_hwdrv_InsnConfigAnalogOutput)(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
int (*i_hwdrv_InsnWriteAnalogOutput)(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
int (*i_hwdrv_InsnBitsAnalogOutput)(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
|
||||
/* Digital Input */
|
||||
int (*i_hwdrv_InsnConfigDigitalInput) (struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
int (*i_hwdrv_InsnReadDigitalInput) (struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
int (*i_hwdrv_InsnWriteDigitalInput) (struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
int (*i_hwdrv_InsnBitsDigitalInput) (struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
|
||||
/* Digital Output */
|
||||
int (*i_hwdrv_InsnConfigDigitalOutput)(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
int (*i_hwdrv_InsnWriteDigitalOutput)(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
int (*i_hwdrv_InsnBitsDigitalOutput)(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
int (*i_hwdrv_InsnReadDigitalOutput)(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
|
||||
/* TIMER */
|
||||
int (*i_hwdrv_InsnConfigTimer)(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
int (*i_hwdrv_InsnWriteTimer)(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
int (*i_hwdrv_InsnReadTimer)(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
int (*i_hwdrv_InsnBitsTimer)(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
/* TTL IO */
|
||||
int (*i_hwdr_ConfigInitTTLIO)(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
int (*i_hwdr_ReadTTLIOBits)(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
int (*i_hwdr_ReadTTLIOAllPortValue)(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
int (*i_hwdr_WriteTTLIOChlOnOff)(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
} boardtype;
|
||||
|
||||
//MODULE INFO STRUCTURE
|
||||
|
||||
typedef union {
|
||||
/* Incremental counter infos */
|
||||
struct {
|
||||
union {
|
||||
struct {
|
||||
BYTE b_ModeRegister1;
|
||||
BYTE b_ModeRegister2;
|
||||
BYTE b_ModeRegister3;
|
||||
BYTE b_ModeRegister4;
|
||||
} s_ByteModeRegister;
|
||||
DWORD dw_ModeRegister1_2_3_4;
|
||||
} s_ModeRegister;
|
||||
|
||||
struct {
|
||||
unsigned int b_IndexInit:1;
|
||||
unsigned int b_CounterInit:1;
|
||||
unsigned int b_ReferenceInit:1;
|
||||
unsigned int b_IndexInterruptOccur:1;
|
||||
unsigned int b_CompareLogicInit:1;
|
||||
unsigned int b_FrequencyMeasurementInit:1;
|
||||
unsigned int b_FrequencyMeasurementEnable:1;
|
||||
} s_InitFlag;
|
||||
|
||||
} s_SiemensCounterInfo;
|
||||
|
||||
/* SSI infos */
|
||||
struct {
|
||||
BYTE b_SSIProfile;
|
||||
BYTE b_PositionTurnLength;
|
||||
BYTE b_TurnCptLength;
|
||||
BYTE b_SSIInit;
|
||||
} s_SSICounterInfo;
|
||||
|
||||
/* TTL I/O infos */
|
||||
struct {
|
||||
BYTE b_TTLInit;
|
||||
BYTE b_PortConfiguration[4];
|
||||
} s_TTLIOInfo;
|
||||
|
||||
/* Digital I/O infos */
|
||||
struct {
|
||||
BYTE b_DigitalInit;
|
||||
BYTE b_ChannelAMode;
|
||||
BYTE b_ChannelBMode;
|
||||
BYTE b_OutputMemoryEnabled;
|
||||
DWORD dw_OutputMemory;
|
||||
} s_DigitalIOInfo;
|
||||
|
||||
/*********************/
|
||||
/* 82X54 timer infos */
|
||||
/*********************/
|
||||
|
||||
struct {
|
||||
struct {
|
||||
BYTE b_82X54Init;
|
||||
BYTE b_InputClockSelection;
|
||||
BYTE b_InputClockLevel;
|
||||
BYTE b_OutputLevel;
|
||||
BYTE b_HardwareGateLevel;
|
||||
DWORD dw_ConfigurationWord;
|
||||
} s_82X54TimerInfo[3];
|
||||
BYTE b_InterruptMask;
|
||||
} s_82X54ModuleInfo;
|
||||
|
||||
/*********************/
|
||||
/* Chronometer infos */
|
||||
/*********************/
|
||||
|
||||
struct {
|
||||
BYTE b_ChronoInit;
|
||||
BYTE b_InterruptMask;
|
||||
BYTE b_PCIInputClock;
|
||||
BYTE b_TimingUnit;
|
||||
BYTE b_CycleMode;
|
||||
double d_TimingInterval;
|
||||
DWORD dw_ConfigReg;
|
||||
} s_ChronoModuleInfo;
|
||||
|
||||
/***********************/
|
||||
/* Pulse encoder infos */
|
||||
/***********************/
|
||||
|
||||
struct {
|
||||
struct {
|
||||
BYTE b_PulseEncoderInit;
|
||||
} s_PulseEncoderInfo[4];
|
||||
DWORD dw_SetRegister;
|
||||
DWORD dw_ControlRegister;
|
||||
DWORD dw_StatusRegister;
|
||||
} s_PulseEncoderModuleInfo;
|
||||
|
||||
/* Tor conter infos */
|
||||
struct {
|
||||
struct {
|
||||
BYTE b_TorCounterInit;
|
||||
BYTE b_TimingUnit;
|
||||
BYTE b_InterruptEnable;
|
||||
double d_TimingInterval;
|
||||
ULONG ul_RealTimingInterval;
|
||||
} s_TorCounterInfo[2];
|
||||
BYTE b_PCIInputClock;
|
||||
} s_TorCounterModuleInfo;
|
||||
|
||||
/* PWM infos */
|
||||
struct {
|
||||
struct {
|
||||
BYTE b_PWMInit;
|
||||
BYTE b_TimingUnit;
|
||||
BYTE b_InterruptEnable;
|
||||
double d_LowTiming;
|
||||
double d_HighTiming;
|
||||
ULONG ul_RealLowTiming;
|
||||
ULONG ul_RealHighTiming;
|
||||
} s_PWMInfo[2];
|
||||
BYTE b_ClockSelection;
|
||||
} s_PWMModuleInfo;
|
||||
|
||||
/* ETM infos */
|
||||
struct {
|
||||
struct {
|
||||
BYTE b_ETMEnable;
|
||||
BYTE b_ETMInterrupt;
|
||||
} s_ETMInfo[2];
|
||||
BYTE b_ETMInit;
|
||||
BYTE b_TimingUnit;
|
||||
BYTE b_ClockSelection;
|
||||
double d_TimingInterval;
|
||||
ULONG ul_Timing;
|
||||
} s_ETMModuleInfo;
|
||||
|
||||
/* CDA infos */
|
||||
struct {
|
||||
BYTE b_CDAEnable;
|
||||
BYTE b_CDAInterrupt;
|
||||
BYTE b_CDAInit;
|
||||
BYTE b_FctSelection;
|
||||
BYTE b_CDAReadFIFOOverflow;
|
||||
} s_CDAModuleInfo;
|
||||
|
||||
} str_ModuleInfo;
|
||||
|
||||
/* Private structure for the addi_apci3120 driver */
|
||||
typedef struct {
|
||||
|
||||
INT iobase;
|
||||
INT i_IobaseAmcc; // base+size for AMCC chip
|
||||
INT i_IobaseAddon; //addon base address
|
||||
INT i_IobaseReserved;
|
||||
ULONG_PTR dw_AiBase;
|
||||
struct pcilst_struct *amcc; // ptr too AMCC data
|
||||
BYTE allocated; // we have blocked card
|
||||
BYTE b_ValidDriver; // driver is ok
|
||||
BYTE b_AiContinuous; // we do unlimited AI
|
||||
BYTE b_AiInitialisation;
|
||||
UINT ui_AiActualScan; //how many scans we finished
|
||||
UINT ui_AiBufferPtr; // data buffer ptr in samples
|
||||
UINT ui_AiNbrofChannels; // how many channels is measured
|
||||
UINT ui_AiScanLength; // Length of actual scanlist
|
||||
UINT ui_AiActualScanPosition; // position in actual scan
|
||||
PUINT pui_AiChannelList; // actual chanlist
|
||||
UINT ui_AiChannelList[32]; // actual chanlist
|
||||
BYTE b_AiChannelConfiguration[32]; // actual chanlist
|
||||
UINT ui_AiReadData[32];
|
||||
DWORD dw_AiInitialised;
|
||||
UINT ui_AiTimer0; //Timer Constant for Timer0
|
||||
UINT ui_AiTimer1; //Timer constant for Timer1
|
||||
UINT ui_AiFlags;
|
||||
UINT ui_AiDataLength;
|
||||
short *AiData; // Pointer to sample data
|
||||
UINT ui_AiNbrofScans; // number of scans to do
|
||||
USHORT us_UseDma; // To use Dma or not
|
||||
BYTE b_DmaDoubleBuffer; // we can use double buffering
|
||||
UINT ui_DmaActualBuffer; // which buffer is used now
|
||||
//*UPDATE-0.7.57->0.7.68
|
||||
//ULONG ul_DmaBufferVirtual[2];// pointers to begin of DMA buffer
|
||||
short *ul_DmaBufferVirtual[2]; // pointers to begin of DMA buffer
|
||||
ULONG ul_DmaBufferHw[2]; // hw address of DMA buff
|
||||
UINT ui_DmaBufferSize[2]; // size of dma buffer in bytes
|
||||
UINT ui_DmaBufferUsesize[2]; // which size we may now used for transfer
|
||||
UINT ui_DmaBufferSamples[2]; // size in samples
|
||||
UINT ui_DmaBufferPages[2]; // number of pages in buffer
|
||||
BYTE b_DigitalOutputRegister; // Digital Output Register
|
||||
BYTE b_OutputMemoryStatus;
|
||||
BYTE b_AnalogInputChannelNbr; // Analog input channel Nbr
|
||||
BYTE b_AnalogOutputChannelNbr; // Analog input Output Nbr
|
||||
BYTE b_TimerSelectMode; // Contain data written at iobase + 0C
|
||||
BYTE b_ModeSelectRegister; // Contain data written at iobase + 0E
|
||||
USHORT us_OutputRegister; // Contain data written at iobase + 0
|
||||
BYTE b_InterruptState;
|
||||
BYTE b_TimerInit; // Specify if InitTimerWatchdog was load
|
||||
BYTE b_TimerStarted; // Specify if timer 2 is running or not
|
||||
BYTE b_Timer2Mode; // Specify the timer 2 mode
|
||||
BYTE b_Timer2Interrupt; //Timer2 interrupt enable or disable
|
||||
BYTE b_AiCyclicAcquisition; // indicate cyclic acquisition
|
||||
BYTE b_InterruptMode; // eoc eos or dma
|
||||
BYTE b_EocEosInterrupt; // Enable disable eoc eos interrupt
|
||||
UINT ui_EocEosConversionTime;
|
||||
BYTE b_EocEosConversionTimeBase;
|
||||
BYTE b_SingelDiff;
|
||||
BYTE b_ExttrigEnable; /* To enable or disable external trigger */
|
||||
|
||||
/* Pointer to the current process */
|
||||
struct task_struct *tsk_Current;
|
||||
boardtype *ps_BoardInfo;
|
||||
|
||||
/* Hardware board infos for 1710 */
|
||||
struct {
|
||||
UINT ui_Address; /* Board address */
|
||||
UINT ui_FlashAddress;
|
||||
BYTE b_InterruptNbr; /* Board interrupt number */
|
||||
BYTE b_SlotNumber; /* PCI slot number */
|
||||
BYTE b_BoardVersion;
|
||||
DWORD dw_MolduleConfiguration[4]; /* Module config */
|
||||
} s_BoardInfos;
|
||||
|
||||
/* Interrupt infos */
|
||||
struct {
|
||||
ULONG ul_InterruptOccur; /* 0 : No interrupt occur */
|
||||
/* > 0 : Interrupt occur */
|
||||
UINT ui_Read; /* Read FIFO */
|
||||
UINT ui_Write; /* Write FIFO */
|
||||
struct {
|
||||
BYTE b_OldModuleMask;
|
||||
ULONG ul_OldInterruptMask; /* Interrupt mask */
|
||||
ULONG ul_OldCounterLatchValue; /* Interrupt counter value */
|
||||
} s_FIFOInterruptParameters[APCI1710_SAVE_INTERRUPT];
|
||||
} s_InterruptParameters;
|
||||
|
||||
str_ModuleInfo s_ModuleInfo[4];
|
||||
ULONG ul_TTLPortConfiguration[10];
|
||||
|
||||
} addi_private;
|
||||
|
||||
static unsigned short pci_list_builded; /* set to 1 when list of card is known */
|
||||
|
||||
/* Function declarations */
|
||||
static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int i_ADDI_Detach(struct comedi_device *dev);
|
||||
static int i_ADDI_Reset(struct comedi_device *dev);
|
||||
|
||||
static irqreturn_t v_ADDI_Interrupt(int irq, void *d PT_REGS_ARG);
|
||||
static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,457 @@
|
|||
/*
|
||||
Modified by umesh on 16th may 2001
|
||||
Modified by sarath on 22nd may 2001
|
||||
*/
|
||||
|
||||
/*
|
||||
comedi/drivers/amcc_s5933_v_58.h
|
||||
|
||||
Stuff for AMCC S5933 PCI Controller
|
||||
|
||||
Author: Michal Dobes <majkl@tesnet.cz>
|
||||
|
||||
Inspirated from general-purpose AMCC S5933 PCI Matchmaker driver
|
||||
made by Andrea Cisternino <acister@pcape1.pi.infn.it>
|
||||
and as result of espionage from MITE code made by David A. Schleef.
|
||||
Thanks to AMCC for their on-line documentation and bus master DMA
|
||||
example.
|
||||
*/
|
||||
|
||||
#ifndef _AMCC_S5933_H_
|
||||
#define _AMCC_S5933_H_
|
||||
|
||||
#include <linux/pci.h>
|
||||
#include "../../comedidev.h"
|
||||
|
||||
#ifdef PCI_SUPPORT_VER1
|
||||
#error Sorry, no support for 2.1.55 and older! :-((((
|
||||
#endif
|
||||
|
||||
/***********Added by sarath for compatibility with APCI3120
|
||||
|
||||
*************************/
|
||||
|
||||
#define FIFO_ADVANCE_ON_BYTE_2 0x20000000 // written on base0
|
||||
|
||||
#define AMWEN_ENABLE 0x02 // added for step 6 dma written on base2
|
||||
#define A2P_FIFO_WRITE_ENABLE 0x01
|
||||
|
||||
#define AGCSTS_TC_ENABLE 0x10000000 // Added for transfer count enable bit
|
||||
|
||||
// ADDON RELATED ADDITIONS
|
||||
// Constant
|
||||
#define APCI3120_ENABLE_TRANSFER_ADD_ON_LOW 0x00
|
||||
#define APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH 0x1200
|
||||
#define APCI3120_A2P_FIFO_MANAGEMENT 0x04000400L
|
||||
#define APCI3120_AMWEN_ENABLE 0x02
|
||||
#define APCI3120_A2P_FIFO_WRITE_ENABLE 0x01
|
||||
#define APCI3120_FIFO_ADVANCE_ON_BYTE_2 0x20000000L
|
||||
#define APCI3120_ENABLE_WRITE_TC_INT 0x00004000L
|
||||
#define APCI3120_CLEAR_WRITE_TC_INT 0x00040000L
|
||||
#define APCI3120_DISABLE_AMWEN_AND_A2P_FIFO_WRITE 0x0
|
||||
#define APCI3120_DISABLE_BUS_MASTER_ADD_ON 0x0
|
||||
#define APCI3120_DISABLE_BUS_MASTER_PCI 0x0
|
||||
|
||||
// ADD_ON ::: this needed since apci supports 16 bit interface to add on
|
||||
#define APCI3120_ADD_ON_AGCSTS_LOW 0x3C
|
||||
#define APCI3120_ADD_ON_AGCSTS_HIGH APCI3120_ADD_ON_AGCSTS_LOW + 2
|
||||
#define APCI3120_ADD_ON_MWAR_LOW 0x24
|
||||
#define APCI3120_ADD_ON_MWAR_HIGH APCI3120_ADD_ON_MWAR_LOW + 2
|
||||
#define APCI3120_ADD_ON_MWTC_LOW 0x058
|
||||
#define APCI3120_ADD_ON_MWTC_HIGH APCI3120_ADD_ON_MWTC_LOW + 2
|
||||
|
||||
// AMCC
|
||||
#define APCI3120_AMCC_OP_MCSR 0x3C
|
||||
#define APCI3120_AMCC_OP_REG_INTCSR 0x38
|
||||
|
||||
/*******from here all upward definitions are added by sarath */
|
||||
|
||||
/****************************************************************************/
|
||||
/* AMCC Operation Register Offsets - PCI */
|
||||
/****************************************************************************/
|
||||
|
||||
#define AMCC_OP_REG_OMB1 0x00
|
||||
#define AMCC_OP_REG_OMB2 0x04
|
||||
#define AMCC_OP_REG_OMB3 0x08
|
||||
#define AMCC_OP_REG_OMB4 0x0c
|
||||
#define AMCC_OP_REG_IMB1 0x10
|
||||
#define AMCC_OP_REG_IMB2 0x14
|
||||
#define AMCC_OP_REG_IMB3 0x18
|
||||
#define AMCC_OP_REG_IMB4 0x1c
|
||||
#define AMCC_OP_REG_FIFO 0x20
|
||||
#define AMCC_OP_REG_MWAR 0x24
|
||||
#define AMCC_OP_REG_MWTC 0x28
|
||||
#define AMCC_OP_REG_MRAR 0x2c
|
||||
#define AMCC_OP_REG_MRTC 0x30
|
||||
#define AMCC_OP_REG_MBEF 0x34
|
||||
#define AMCC_OP_REG_INTCSR 0x38
|
||||
#define AMCC_OP_REG_INTCSR_SRC (AMCC_OP_REG_INTCSR + 2) /* INT source */
|
||||
#define AMCC_OP_REG_INTCSR_FEC (AMCC_OP_REG_INTCSR + 3) /* FIFO ctrl */
|
||||
#define AMCC_OP_REG_MCSR 0x3c
|
||||
#define AMCC_OP_REG_MCSR_NVDATA (AMCC_OP_REG_MCSR + 2) /* Data in byte 2 */
|
||||
#define AMCC_OP_REG_MCSR_NVCMD (AMCC_OP_REG_MCSR + 3) /* Command in byte 3 */
|
||||
|
||||
#define AMCC_FIFO_DEPTH_DWORD 8
|
||||
#define AMCC_FIFO_DEPTH_BYTES (8 * sizeof (u32))
|
||||
|
||||
/****************************************************************************/
|
||||
/* AMCC Operation Registers Size - PCI */
|
||||
/****************************************************************************/
|
||||
|
||||
#define AMCC_OP_REG_SIZE 64 /* in bytes */
|
||||
|
||||
/****************************************************************************/
|
||||
/* AMCC Operation Register Offsets - Add-on */
|
||||
/****************************************************************************/
|
||||
|
||||
#define AMCC_OP_REG_AIMB1 0x00
|
||||
#define AMCC_OP_REG_AIMB2 0x04
|
||||
#define AMCC_OP_REG_AIMB3 0x08
|
||||
#define AMCC_OP_REG_AIMB4 0x0c
|
||||
#define AMCC_OP_REG_AOMB1 0x10
|
||||
#define AMCC_OP_REG_AOMB2 0x14
|
||||
#define AMCC_OP_REG_AOMB3 0x18
|
||||
#define AMCC_OP_REG_AOMB4 0x1c
|
||||
#define AMCC_OP_REG_AFIFO 0x20
|
||||
#define AMCC_OP_REG_AMWAR 0x24
|
||||
#define AMCC_OP_REG_APTA 0x28
|
||||
#define AMCC_OP_REG_APTD 0x2c
|
||||
#define AMCC_OP_REG_AMRAR 0x30
|
||||
#define AMCC_OP_REG_AMBEF 0x34
|
||||
#define AMCC_OP_REG_AINT 0x38
|
||||
#define AMCC_OP_REG_AGCSTS 0x3c
|
||||
#define AMCC_OP_REG_AMWTC 0x58
|
||||
#define AMCC_OP_REG_AMRTC 0x5c
|
||||
|
||||
/****************************************************************************/
|
||||
/* AMCC - Add-on General Control/Status Register */
|
||||
/****************************************************************************/
|
||||
|
||||
#define AGCSTS_CONTROL_MASK 0xfffff000
|
||||
#define AGCSTS_NV_ACC_MASK 0xe0000000
|
||||
#define AGCSTS_RESET_MASK 0x0e000000
|
||||
#define AGCSTS_NV_DA_MASK 0x00ff0000
|
||||
#define AGCSTS_BIST_MASK 0x0000f000
|
||||
#define AGCSTS_STATUS_MASK 0x000000ff
|
||||
#define AGCSTS_TCZERO_MASK 0x000000c0
|
||||
#define AGCSTS_FIFO_ST_MASK 0x0000003f
|
||||
|
||||
#define AGCSTS_RESET_MBFLAGS 0x08000000
|
||||
#define AGCSTS_RESET_P2A_FIFO 0x04000000
|
||||
#define AGCSTS_RESET_A2P_FIFO 0x02000000
|
||||
#define AGCSTS_RESET_FIFOS (AGCSTS_RESET_A2P_FIFO | AGCSTS_RESET_P2A_FIFO)
|
||||
|
||||
#define AGCSTS_A2P_TCOUNT 0x00000080
|
||||
#define AGCSTS_P2A_TCOUNT 0x00000040
|
||||
|
||||
#define AGCSTS_FS_P2A_EMPTY 0x00000020
|
||||
#define AGCSTS_FS_P2A_HALF 0x00000010
|
||||
#define AGCSTS_FS_P2A_FULL 0x00000008
|
||||
|
||||
#define AGCSTS_FS_A2P_EMPTY 0x00000004
|
||||
#define AGCSTS_FS_A2P_HALF 0x00000002
|
||||
#define AGCSTS_FS_A2P_FULL 0x00000001
|
||||
|
||||
/****************************************************************************/
|
||||
/* AMCC - Add-on Interrupt Control/Status Register */
|
||||
/****************************************************************************/
|
||||
|
||||
#define AINT_INT_MASK 0x00ff0000
|
||||
#define AINT_SEL_MASK 0x0000ffff
|
||||
#define AINT_IS_ENSEL_MASK 0x00001f1f
|
||||
|
||||
#define AINT_INT_ASSERTED 0x00800000
|
||||
#define AINT_BM_ERROR 0x00200000
|
||||
#define AINT_BIST_INT 0x00100000
|
||||
|
||||
#define AINT_RT_COMPLETE 0x00080000
|
||||
#define AINT_WT_COMPLETE 0x00040000
|
||||
|
||||
#define AINT_OUT_MB_INT 0x00020000
|
||||
#define AINT_IN_MB_INT 0x00010000
|
||||
|
||||
#define AINT_READ_COMPL 0x00008000
|
||||
#define AINT_WRITE_COMPL 0x00004000
|
||||
|
||||
#define AINT_OMB_ENABLE 0x00001000
|
||||
#define AINT_OMB_SELECT 0x00000c00
|
||||
#define AINT_OMB_BYTE 0x00000300
|
||||
|
||||
#define AINT_IMB_ENABLE 0x00000010
|
||||
#define AINT_IMB_SELECT 0x0000000c
|
||||
#define AINT_IMB_BYTE 0x00000003
|
||||
|
||||
/* Enable Bus Mastering */
|
||||
#define EN_A2P_TRANSFERS 0x00000400
|
||||
/* FIFO Flag Reset */
|
||||
#define RESET_A2P_FLAGS 0x04000000L
|
||||
/* FIFO Relative Priority */
|
||||
#define A2P_HI_PRIORITY 0x00000100L
|
||||
/* Identify Interrupt Sources */
|
||||
#define ANY_S593X_INT 0x00800000L
|
||||
#define READ_TC_INT 0x00080000L
|
||||
#define WRITE_TC_INT 0x00040000L
|
||||
#define IN_MB_INT 0x00020000L
|
||||
#define MASTER_ABORT_INT 0x00100000L
|
||||
#define TARGET_ABORT_INT 0x00200000L
|
||||
#define BUS_MASTER_INT 0x00200000L
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
struct pcilst_struct {
|
||||
struct pcilst_struct *next;
|
||||
int used;
|
||||
struct pci_dev *pcidev;
|
||||
unsigned short vendor;
|
||||
unsigned short device;
|
||||
unsigned int master;
|
||||
unsigned char pci_bus;
|
||||
unsigned char pci_slot;
|
||||
unsigned char pci_func;
|
||||
unsigned int io_addr[5];
|
||||
unsigned int irq;
|
||||
};
|
||||
|
||||
struct pcilst_struct *amcc_devices; // ptr to root list of all amcc devices
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
void v_pci_card_list_init(unsigned short pci_vendor, char display);
|
||||
void v_pci_card_list_cleanup(unsigned short pci_vendor);
|
||||
struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id,
|
||||
unsigned short
|
||||
device_id);
|
||||
int i_find_free_pci_card_by_position(unsigned short vendor_id,
|
||||
unsigned short device_id,
|
||||
unsigned short pci_bus,
|
||||
unsigned short pci_slot,
|
||||
struct pcilst_struct **card);
|
||||
struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id,
|
||||
unsigned short device_id,
|
||||
unsigned short pci_bus,
|
||||
unsigned short pci_slot);
|
||||
|
||||
int i_pci_card_alloc(struct pcilst_struct *amcc);
|
||||
int i_pci_card_free(struct pcilst_struct *amcc);
|
||||
void v_pci_card_list_display(void);
|
||||
int i_pci_card_data(struct pcilst_struct *amcc,
|
||||
unsigned char *pci_bus, unsigned char *pci_slot,
|
||||
unsigned char *pci_func, unsigned short *io_addr,
|
||||
unsigned short *irq, unsigned short *master);
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* build list of amcc cards in this system */
|
||||
void v_pci_card_list_init(unsigned short pci_vendor, char display)
|
||||
{
|
||||
struct pci_dev *pcidev;
|
||||
struct pcilst_struct *amcc, *last;
|
||||
int i;
|
||||
|
||||
amcc_devices = NULL;
|
||||
last = NULL;
|
||||
|
||||
pci_for_each_dev(pcidev) {
|
||||
if (pcidev->vendor == pci_vendor) {
|
||||
amcc = kmalloc(sizeof(*amcc), GFP_KERNEL);
|
||||
memset(amcc, 0, sizeof(*amcc));
|
||||
|
||||
amcc->pcidev = pcidev;
|
||||
if (last) {
|
||||
last->next = amcc;
|
||||
} else {
|
||||
amcc_devices = amcc;
|
||||
}
|
||||
last = amcc;
|
||||
|
||||
amcc->vendor = pcidev->vendor;
|
||||
amcc->device = pcidev->device;
|
||||
#if 0
|
||||
amcc->master = pcidev->master; // how get this information under 2.4 kernels?
|
||||
#endif
|
||||
amcc->pci_bus = pcidev->bus->number;
|
||||
amcc->pci_slot = PCI_SLOT(pcidev->devfn);
|
||||
amcc->pci_func = PCI_FUNC(pcidev->devfn);
|
||||
for (i = 0; i < 5; i++)
|
||||
amcc->io_addr[i] =
|
||||
pcidev->resource[i].start & ~3UL;
|
||||
amcc->irq = pcidev->irq;
|
||||
}
|
||||
}
|
||||
|
||||
if (display)
|
||||
v_pci_card_list_display();
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* free up list of amcc cards in this system */
|
||||
void v_pci_card_list_cleanup(unsigned short pci_vendor)
|
||||
{
|
||||
struct pcilst_struct *amcc, *next;
|
||||
|
||||
for (amcc = amcc_devices; amcc; amcc = next) {
|
||||
next = amcc->next;
|
||||
kfree(amcc);
|
||||
}
|
||||
|
||||
amcc_devices = NULL;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* find first unused card with this device_id */
|
||||
struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id,
|
||||
unsigned short device_id)
|
||||
{
|
||||
struct pcilst_struct *amcc, *next;
|
||||
|
||||
for (amcc = amcc_devices; amcc; amcc = next) {
|
||||
next = amcc->next;
|
||||
if ((!amcc->used) && (amcc->device == device_id)
|
||||
&& (amcc->vendor == vendor_id))
|
||||
return amcc;
|
||||
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* find card on requested position */
|
||||
int i_find_free_pci_card_by_position(unsigned short vendor_id,
|
||||
unsigned short device_id,
|
||||
unsigned short pci_bus,
|
||||
unsigned short pci_slot,
|
||||
struct pcilst_struct **card)
|
||||
{
|
||||
struct pcilst_struct *amcc, *next;
|
||||
|
||||
*card = NULL;
|
||||
for (amcc = amcc_devices; amcc; amcc = next) {
|
||||
next = amcc->next;
|
||||
if ((amcc->vendor == vendor_id) && (amcc->device == device_id)
|
||||
&& (amcc->pci_bus == pci_bus)
|
||||
&& (amcc->pci_slot == pci_slot)) {
|
||||
if (!(amcc->used)) {
|
||||
*card = amcc;
|
||||
return 0; // ok, card is found
|
||||
} else {
|
||||
rt_printk
|
||||
(" - \nCard on requested position is used b:s %d:%d!\n",
|
||||
pci_bus, pci_slot);
|
||||
return 2; // card exist but is used
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1; // no card found
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* mark card as used */
|
||||
int i_pci_card_alloc(struct pcilst_struct *amcc)
|
||||
{
|
||||
if (!amcc)
|
||||
return -1;
|
||||
|
||||
if (amcc->used)
|
||||
return 1;
|
||||
amcc->used = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* mark card as free */
|
||||
int i_pci_card_free(struct pcilst_struct *amcc)
|
||||
{
|
||||
if (!amcc)
|
||||
return -1;
|
||||
|
||||
if (!amcc->used)
|
||||
return 1;
|
||||
amcc->used = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* display list of found cards */
|
||||
void v_pci_card_list_display(void)
|
||||
{
|
||||
struct pcilst_struct *amcc, *next;
|
||||
|
||||
printk("List of pci cards\n");
|
||||
printk("bus:slot:func vendor device master io_amcc io_daq irq used\n");
|
||||
|
||||
for (amcc = amcc_devices; amcc; amcc = next) {
|
||||
next = amcc->next;
|
||||
printk
|
||||
("%2d %2d %2d 0x%4x 0x%4x %3s 0x%4x 0x%4x %2d %2d\n",
|
||||
amcc->pci_bus, amcc->pci_slot, amcc->pci_func,
|
||||
amcc->vendor, amcc->device, amcc->master ? "yes" : "no",
|
||||
amcc->io_addr[0], amcc->io_addr[2], amcc->irq, amcc->used);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* return all card information for driver */
|
||||
int i_pci_card_data(struct pcilst_struct *amcc,
|
||||
unsigned char *pci_bus, unsigned char *pci_slot,
|
||||
unsigned char *pci_func, unsigned short *io_addr,
|
||||
unsigned short *irq, unsigned short *master)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!amcc)
|
||||
return -1;
|
||||
*pci_bus = amcc->pci_bus;
|
||||
*pci_slot = amcc->pci_slot;
|
||||
*pci_func = amcc->pci_func;
|
||||
for (i = 0; i < 5; i++)
|
||||
io_addr[i] = amcc->io_addr[i];
|
||||
*irq = amcc->irq;
|
||||
*master = amcc->master;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* select and alloc card */
|
||||
struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id,
|
||||
unsigned short device_id,
|
||||
unsigned short pci_bus,
|
||||
unsigned short pci_slot)
|
||||
{
|
||||
struct pcilst_struct *card;
|
||||
|
||||
if ((pci_bus < 1) & (pci_slot < 1)) { // use autodetection
|
||||
if ((card = ptr_find_free_pci_card_by_device(vendor_id,
|
||||
device_id)) ==
|
||||
NULL) {
|
||||
rt_printk(" - Unused card not found in system!\n");
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
switch (i_find_free_pci_card_by_position(vendor_id, device_id,
|
||||
pci_bus, pci_slot,
|
||||
&card)) {
|
||||
case 1:
|
||||
rt_printk
|
||||
(" - Card not found on requested position b:s %d:%d!\n",
|
||||
pci_bus, pci_slot);
|
||||
return NULL;
|
||||
case 2:
|
||||
rt_printk
|
||||
(" - Card on requested position is used b:s %d:%d!\n",
|
||||
pci_bus, pci_slot);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (i_pci_card_alloc(card) != 0) {
|
||||
rt_printk(" - Can't allocate card!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return card;
|
||||
}
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
*
|
||||
* ADDI-DATA GmbH
|
||||
* Dieselstrasse 3
|
||||
* D-77833 Ottersweier
|
||||
* Tel: +19(0)7223/9493-0
|
||||
* Fax: +49(0)7223/9493-92
|
||||
* http://www.addi-data-com
|
||||
* info@addi-data.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*/
|
||||
|
||||
#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */
|
||||
#define COMEDI_SUBD_PWM 12 /* Pulse width Measurement */
|
||||
#define COMEDI_SUBD_SSI 13 /* Synchronous serial interface */
|
||||
#define COMEDI_SUBD_TOR 14 /* Tor counter */
|
||||
#define COMEDI_SUBD_CHRONO 15 /* Chrono meter */
|
||||
#define COMEDI_SUBD_PULSEENCODER 16 /* Pulse Encoder INP CPT */
|
||||
#define COMEDI_SUBD_INCREMENTALCOUNTER 17 /* Incremental Counter */
|
||||
|
||||
#define APCI1710_BOARD_NAME "apci1710"
|
||||
#define APCI1710_BOARD_VENDOR_ID 0x10E8
|
||||
#define APCI1710_BOARD_DEVICE_ID 0x818F
|
||||
#define APCI1710_ADDRESS_RANGE 256
|
||||
#define APCI1710_CONFIG_ADDRESS_RANGE 8
|
||||
#define APCI1710_INCREMENTAL_COUNTER 0x53430000UL
|
||||
#define APCI1710_SSI_COUNTER 0x53490000UL
|
||||
#define APCI1710_TTL_IO 0x544C0000UL
|
||||
#define APCI1710_DIGITAL_IO 0x44490000UL
|
||||
#define APCI1710_82X54_TIMER 0x49430000UL
|
||||
#define APCI1710_CHRONOMETER 0x43480000UL
|
||||
#define APCI1710_PULSE_ENCODER 0x495A0000UL
|
||||
#define APCI1710_TOR_COUNTER 0x544F0000UL
|
||||
#define APCI1710_PWM 0x50570000UL
|
||||
#define APCI1710_ETM 0x45540000UL
|
||||
#define APCI1710_CDA 0x43440000UL
|
||||
#define APCI1710_DISABLE 0
|
||||
#define APCI1710_ENABLE 1
|
||||
#define APCI1710_SYNCHRONOUS_MODE 1
|
||||
#define APCI1710_ASYNCHRONOUS_MODE 0
|
||||
|
||||
//MODULE INFO STRUCTURE
|
||||
|
||||
static const struct comedi_lrange range_apci1710_ttl = { 4, {
|
||||
BIP_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(2),
|
||||
BIP_RANGE(1)
|
||||
}
|
||||
};
|
||||
|
||||
static const struct comedi_lrange range_apci1710_ssi = { 4, {
|
||||
BIP_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(2),
|
||||
BIP_RANGE(1)
|
||||
}
|
||||
};
|
||||
|
||||
static const struct comedi_lrange range_apci1710_inccpt = { 4, {
|
||||
BIP_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(2),
|
||||
BIP_RANGE(1)
|
||||
}
|
||||
};
|
|
@ -0,0 +1,600 @@
|
|||
/**
|
||||
@verbatim
|
||||
|
||||
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
|
||||
ADDI-DATA GmbH
|
||||
Dieselstrasse 3
|
||||
D-77833 Ottersweier
|
||||
Tel: +19(0)7223/9493-0
|
||||
Fax: +49(0)7223/9493-92
|
||||
http://www.addi-data-com
|
||||
info@addi-data.com
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
You shoud also find the complete GPL in the COPYING file accompanying this source code.
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
/*
|
||||
|
||||
+-----------------------------------------------------------------------+
|
||||
| (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
|
||||
+-----------------------------------------------------------------------+
|
||||
| Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
|
||||
| Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
|
||||
+-------------------------------+---------------------------------------+
|
||||
| Project : APCI-035 | Compiler : GCC |
|
||||
| Module name : hwdrv_apci035.c | Version : 2.96 |
|
||||
+-------------------------------+---------------------------------------+
|
||||
| Project manager: Eric Stolz | Date : 02/12/2002 |
|
||||
+-------------------------------+---------------------------------------+
|
||||
| Description : Hardware Layer Acces For APCI-035 |
|
||||
+-----------------------------------------------------------------------+
|
||||
| UPDATES |
|
||||
+----------+-----------+------------------------------------------------+
|
||||
| Date | Author | Description of updates |
|
||||
+----------+-----------+------------------------------------------------+
|
||||
| | | |
|
||||
| | | |
|
||||
| | | |
|
||||
+----------+-----------+------------------------------------------------+
|
||||
*/
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Included files |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
#include "hwdrv_apci035.h"
|
||||
INT i_WatchdogNbr = 0;
|
||||
INT i_Temp = 0;
|
||||
INT i_Flag = 1;
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI035_ConfigTimerWatchdog |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s, |
|
||||
| struct comedi_insn *insn,unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Configures The Timer , Counter or Watchdog |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| UINT *data : Data Pointer contains |
|
||||
| configuration parameters as below |
|
||||
| |
|
||||
| data[0] : 0 Configure As Timer |
|
||||
| 1 Configure As Watchdog |
|
||||
data[1] : Watchdog number
|
||||
| data[2] : Time base Unit |
|
||||
| data[3] : Reload Value |
|
||||
data[4] : External Trigger |
|
||||
1:Enable
|
||||
0:Disable
|
||||
data[5] :External Trigger Level
|
||||
00 Trigger Disabled
|
||||
01 Trigger Enabled (Low level)
|
||||
10 Trigger Enabled (High Level)
|
||||
11 Trigger Enabled (High/Low level)
|
||||
data[6] : External Gate |
|
||||
1:Enable
|
||||
0:Disable
|
||||
data[7] : External Gate level
|
||||
00 Gate Disabled
|
||||
01 Gate Enabled (Low level)
|
||||
10 Gate Enabled (High Level)
|
||||
data[8] :Warning Relay
|
||||
1: ENABLE
|
||||
0: DISABLE
|
||||
data[9] :Warning Delay available
|
||||
data[10] :Warning Relay Time unit
|
||||
data[11] :Warning Relay Time Reload value
|
||||
data[12] :Reset Relay
|
||||
1 : ENABLE
|
||||
0 : DISABLE
|
||||
data[13] :Interrupt
|
||||
1 : ENABLE
|
||||
0 : DISABLE
|
||||
|
||||
|
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
INT i_APCI035_ConfigTimerWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
UINT ui_Status = 0;
|
||||
UINT ui_Command = 0;
|
||||
UINT ui_Mode = 0;
|
||||
i_Temp = 0;
|
||||
devpriv->tsk_Current = current;
|
||||
devpriv->b_TimerSelectMode = data[0];
|
||||
i_WatchdogNbr = data[1];
|
||||
if (data[0] == 0) {
|
||||
ui_Mode = 2;
|
||||
} else {
|
||||
ui_Mode = 0;
|
||||
}
|
||||
//ui_Command = inl(devpriv->iobase+((i_WatchdogNbr-1)*32)+12);
|
||||
ui_Command = 0;
|
||||
//ui_Command = ui_Command & 0xFFFFF9FEUL;
|
||||
outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
|
||||
ui_Command = 0;
|
||||
ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
|
||||
/************************/
|
||||
/* Set the reload value */
|
||||
/************************/
|
||||
outl(data[3], devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 4);
|
||||
/*********************/
|
||||
/* Set the time unit */
|
||||
/*********************/
|
||||
outl(data[2], devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 8);
|
||||
if (data[0] == ADDIDATA_TIMER) {
|
||||
|
||||
/******************************/
|
||||
/* Set the mode : */
|
||||
/* - Disable the hardware */
|
||||
/* - Disable the counter mode */
|
||||
/* - Disable the warning */
|
||||
/* - Disable the reset */
|
||||
/* - Enable the timer mode */
|
||||
/* - Set the timer mode */
|
||||
/******************************/
|
||||
|
||||
ui_Command =
|
||||
(ui_Command & 0xFFF719E2UL) | ui_Mode << 13UL | 0x10UL;
|
||||
|
||||
} //if (data[0] == ADDIDATA_TIMER)
|
||||
else {
|
||||
if (data[0] == ADDIDATA_WATCHDOG) {
|
||||
|
||||
/******************************/
|
||||
/* Set the mode : */
|
||||
/* - Disable the hardware */
|
||||
/* - Disable the counter mode */
|
||||
/* - Disable the warning */
|
||||
/* - Disable the reset */
|
||||
/* - Disable the timer mode */
|
||||
/******************************/
|
||||
|
||||
ui_Command = ui_Command & 0xFFF819E2UL;
|
||||
|
||||
} else {
|
||||
printk("\n The parameter for Timer/watchdog selection is in error\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
|
||||
ui_Command = 0;
|
||||
ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
|
||||
/********************************/
|
||||
/* Disable the hardware trigger */
|
||||
/********************************/
|
||||
ui_Command = ui_Command & 0xFFFFF89FUL;
|
||||
if (data[4] == ADDIDATA_ENABLE) {
|
||||
/**********************************/
|
||||
/* Set the hardware trigger level */
|
||||
/**********************************/
|
||||
ui_Command = ui_Command | (data[5] << 5);
|
||||
}
|
||||
outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
|
||||
ui_Command = 0;
|
||||
ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
|
||||
/*****************************/
|
||||
/* Disable the hardware gate */
|
||||
/*****************************/
|
||||
ui_Command = ui_Command & 0xFFFFF87FUL;
|
||||
if (data[6] == ADDIDATA_ENABLE) {
|
||||
/*******************************/
|
||||
/* Set the hardware gate level */
|
||||
/*******************************/
|
||||
ui_Command = ui_Command | (data[7] << 7);
|
||||
}
|
||||
outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
|
||||
ui_Command = 0;
|
||||
ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
|
||||
/*******************************/
|
||||
/* Disable the hardware output */
|
||||
/*******************************/
|
||||
ui_Command = ui_Command & 0xFFFFF9FBUL;
|
||||
/*********************************/
|
||||
/* Set the hardware output level */
|
||||
/*********************************/
|
||||
ui_Command = ui_Command | (data[8] << 2);
|
||||
outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
|
||||
if (data[9] == ADDIDATA_ENABLE) {
|
||||
/************************/
|
||||
/* Set the reload value */
|
||||
/************************/
|
||||
outl(data[11],
|
||||
devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 24);
|
||||
/**********************/
|
||||
/* Set the time unite */
|
||||
/**********************/
|
||||
outl(data[10],
|
||||
devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 28);
|
||||
}
|
||||
|
||||
ui_Command = 0;
|
||||
ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
|
||||
/*******************************/
|
||||
/* Disable the hardware output */
|
||||
/*******************************/
|
||||
ui_Command = ui_Command & 0xFFFFF9F7UL;
|
||||
/*********************************/
|
||||
/* Set the hardware output level */
|
||||
/*********************************/
|
||||
ui_Command = ui_Command | (data[12] << 3);
|
||||
outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
|
||||
/*************************************/
|
||||
/** Enable the watchdog interrupt **/
|
||||
/*************************************/
|
||||
ui_Command = 0;
|
||||
ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
|
||||
/*******************************/
|
||||
/* Set the interrupt selection */
|
||||
/*******************************/
|
||||
ui_Status = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 16);
|
||||
|
||||
ui_Command = (ui_Command & 0xFFFFF9FDUL) | (data[13] << 1);
|
||||
outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
|
||||
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI035_StartStopWriteTimerWatchdog |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s, |
|
||||
| struct comedi_insn *insn,unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Start / Stop The Selected Timer , or Watchdog |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| UINT *data : Data Pointer contains |
|
||||
| configuration parameters as below |
|
||||
| |
|
||||
| data[0] : 0 - Stop Selected Timer/Watchdog |
|
||||
| 1 - Start Selected Timer/Watchdog |
|
||||
| 2 - Trigger Selected Timer/Watchdog |
|
||||
| 3 - Stop All Timer/Watchdog |
|
||||
| 4 - Start All Timer/Watchdog |
|
||||
| 5 - Trigger All Timer/Watchdog |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
INT i_APCI035_StartStopWriteTimerWatchdog(struct comedi_device * dev,
|
||||
struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
UINT ui_Command = 0;
|
||||
INT i_Count = 0;
|
||||
if (data[0] == 1) {
|
||||
ui_Command =
|
||||
inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
|
||||
/**********************/
|
||||
/* Start the hardware */
|
||||
/**********************/
|
||||
ui_Command = (ui_Command & 0xFFFFF9FFUL) | 0x1UL;
|
||||
outl(ui_Command,
|
||||
devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
|
||||
} // if (data[0]==1)
|
||||
if (data[0] == 2) {
|
||||
ui_Command =
|
||||
inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
|
||||
/***************************/
|
||||
/* Set the trigger command */
|
||||
/***************************/
|
||||
ui_Command = (ui_Command & 0xFFFFF9FFUL) | 0x200UL;
|
||||
outl(ui_Command,
|
||||
devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
|
||||
}
|
||||
|
||||
if (data[0] == 0) //Stop The Watchdog
|
||||
{
|
||||
//Stop The Watchdog
|
||||
ui_Command = 0;
|
||||
//ui_Command = inl(devpriv->iobase+((i_WatchdogNbr-1)*32)+12);
|
||||
//ui_Command = ui_Command & 0xFFFFF9FEUL;
|
||||
outl(ui_Command,
|
||||
devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
|
||||
} // if (data[1]==0)
|
||||
if (data[0] == 3) //stop all Watchdogs
|
||||
{
|
||||
ui_Command = 0;
|
||||
for (i_Count = 1; i_Count <= 4; i_Count++) {
|
||||
if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
|
||||
ui_Command = 0x2UL;
|
||||
} else {
|
||||
ui_Command = 0x10UL;
|
||||
}
|
||||
i_WatchdogNbr = i_Count;
|
||||
outl(ui_Command,
|
||||
devpriv->iobase + ((i_WatchdogNbr - 1) * 32) +
|
||||
0);
|
||||
}
|
||||
|
||||
}
|
||||
if (data[0] == 4) //start all Watchdogs
|
||||
{
|
||||
ui_Command = 0;
|
||||
for (i_Count = 1; i_Count <= 4; i_Count++) {
|
||||
if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
|
||||
ui_Command = 0x1UL;
|
||||
} else {
|
||||
ui_Command = 0x8UL;
|
||||
}
|
||||
i_WatchdogNbr = i_Count;
|
||||
outl(ui_Command,
|
||||
devpriv->iobase + ((i_WatchdogNbr - 1) * 32) +
|
||||
0);
|
||||
}
|
||||
}
|
||||
if (data[0] == 5) //trigger all Watchdogs
|
||||
{
|
||||
ui_Command = 0;
|
||||
for (i_Count = 1; i_Count <= 4; i_Count++) {
|
||||
if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
|
||||
ui_Command = 0x4UL;
|
||||
} else {
|
||||
ui_Command = 0x20UL;
|
||||
}
|
||||
|
||||
i_WatchdogNbr = i_Count;
|
||||
outl(ui_Command,
|
||||
devpriv->iobase + ((i_WatchdogNbr - 1) * 32) +
|
||||
0);
|
||||
}
|
||||
i_Temp = 1;
|
||||
}
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI035_ReadTimerWatchdog |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s, |
|
||||
| struct comedi_insn *insn,unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Read The Selected Timer , Counter or Watchdog |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| UINT *data : Data Pointer contains |
|
||||
| configuration parameters as below |
|
||||
| |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : data[0] : software trigger status
|
||||
data[1] : hardware trigger status
|
||||
| data[2] : Software clear status
|
||||
data[3] : Overflow status
|
||||
data[4] : Timer actual value
|
||||
|
||||
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
INT i_APCI035_ReadTimerWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
UINT ui_Status = 0; // Status register
|
||||
i_WatchdogNbr = insn->unused[0];
|
||||
/******************/
|
||||
/* Get the status */
|
||||
/******************/
|
||||
ui_Status = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 16);
|
||||
/***********************************/
|
||||
/* Get the software trigger status */
|
||||
/***********************************/
|
||||
data[0] = ((ui_Status >> 1) & 1);
|
||||
/***********************************/
|
||||
/* Get the hardware trigger status */
|
||||
/***********************************/
|
||||
data[1] = ((ui_Status >> 2) & 1);
|
||||
/*********************************/
|
||||
/* Get the software clear status */
|
||||
/*********************************/
|
||||
data[2] = ((ui_Status >> 3) & 1);
|
||||
/***************************/
|
||||
/* Get the overflow status */
|
||||
/***************************/
|
||||
data[3] = ((ui_Status >> 0) & 1);
|
||||
if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) {
|
||||
data[4] = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 0);
|
||||
|
||||
} // if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER)
|
||||
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : INT i_APCI035_ConfigAnalogInput |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s, |
|
||||
| struct comedi_insn *insn,unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Configures The Analog Input Subdevice |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| struct comedi_subdevice *s : Subdevice Pointer |
|
||||
| struct comedi_insn *insn : Insn Structure Pointer |
|
||||
| unsigned int *data : Data Pointer contains |
|
||||
| configuration parameters as below |
|
||||
| data[0] : Warning delay value
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
INT i_APCI035_ConfigAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
devpriv->tsk_Current = current;
|
||||
outl(0x200 | 0, devpriv->iobase + 128 + 0x4);
|
||||
outl(0, devpriv->iobase + 128 + 0);
|
||||
/********************************/
|
||||
/* Initialise the warning value */
|
||||
/********************************/
|
||||
outl(0x300 | 0, devpriv->iobase + 128 + 0x4);
|
||||
outl((data[0] << 8), devpriv->iobase + 128 + 0);
|
||||
outl(0x200000UL, devpriv->iobase + 128 + 12);
|
||||
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI035_ReadAnalogInput |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s, |
|
||||
| struct comedi_insn *insn,unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Read value of the selected channel |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| UINT ui_NoOfChannels : No Of Channels To read |
|
||||
| UINT *data : Data Pointer to read status |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
| data[0] : Digital Value Of Input |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
INT i_APCI035_ReadAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
UINT ui_CommandRegister = 0;
|
||||
/******************/
|
||||
/* Set the start */
|
||||
/******************/
|
||||
ui_CommandRegister = 0x80000;
|
||||
/******************************/
|
||||
/* Write the command register */
|
||||
/******************************/
|
||||
outl(ui_CommandRegister, devpriv->iobase + 128 + 8);
|
||||
|
||||
/***************************************/
|
||||
/* Read the digital value of the input */
|
||||
/***************************************/
|
||||
data[0] = inl(devpriv->iobase + 128 + 28);
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI035_Reset(struct comedi_device *dev) |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task :Resets the registers of the card |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
INT i_APCI035_Reset(struct comedi_device * dev)
|
||||
{
|
||||
INT i_Count = 0;
|
||||
for (i_Count = 1; i_Count <= 4; i_Count++) {
|
||||
i_WatchdogNbr = i_Count;
|
||||
outl(0x0, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 0); //stop all timers
|
||||
}
|
||||
outl(0x0, devpriv->iobase + 128 + 12); //Disable the warning delay
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : static void v_APCI035_Interrupt |
|
||||
| (int irq , void *d) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Interrupt processing Routine |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : int irq : irq number |
|
||||
| void *d : void pointer |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
static void v_APCI035_Interrupt(int irq, void *d)
|
||||
{
|
||||
struct comedi_device *dev = d;
|
||||
UINT ui_StatusRegister1 = 0;
|
||||
UINT ui_StatusRegister2 = 0;
|
||||
UINT ui_ReadCommand = 0;
|
||||
UINT ui_ChannelNumber = 0;
|
||||
UINT ui_DigitalTemperature = 0;
|
||||
if (i_Temp == 1) {
|
||||
i_WatchdogNbr = i_Flag;
|
||||
i_Flag = i_Flag + 1;
|
||||
}
|
||||
/**************************************/
|
||||
/* Read the interrupt status register of temperature Warning */
|
||||
/**************************************/
|
||||
ui_StatusRegister1 = inl(devpriv->iobase + 128 + 16);
|
||||
/**************************************/
|
||||
/* Read the interrupt status register for Watchdog/timer */
|
||||
/**************************************/
|
||||
|
||||
ui_StatusRegister2 =
|
||||
inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 20);
|
||||
|
||||
if ((((ui_StatusRegister1) & 0x8) == 0x8)) //Test if warning relay interrupt
|
||||
{
|
||||
/**********************************/
|
||||
/* Disable the temperature warning */
|
||||
/**********************************/
|
||||
ui_ReadCommand = inl(devpriv->iobase + 128 + 12);
|
||||
ui_ReadCommand = ui_ReadCommand & 0xFFDF0000UL;
|
||||
outl(ui_ReadCommand, devpriv->iobase + 128 + 12);
|
||||
/***************************/
|
||||
/* Read the channel number */
|
||||
/***************************/
|
||||
ui_ChannelNumber = inl(devpriv->iobase + 128 + 60);
|
||||
/**************************************/
|
||||
/* Read the digital temperature value */
|
||||
/**************************************/
|
||||
ui_DigitalTemperature = inl(devpriv->iobase + 128 + 60);
|
||||
send_sig(SIGIO, devpriv->tsk_Current, 0); // send signal to the sample
|
||||
} //if (((ui_StatusRegister1 & 0x8) == 0x8))
|
||||
|
||||
else {
|
||||
if ((ui_StatusRegister2 & 0x1) == 0x1) {
|
||||
send_sig(SIGIO, devpriv->tsk_Current, 0); // send signal to the sample
|
||||
}
|
||||
} //else if (((ui_StatusRegister1 & 0x8) == 0x8))
|
||||
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
*
|
||||
* ADDI-DATA GmbH
|
||||
* Dieselstrasse 3
|
||||
* D-77833 Ottersweier
|
||||
* Tel: +19(0)7223/9493-0
|
||||
* Fax: +49(0)7223/9493-92
|
||||
* http://www.addi-data-com
|
||||
* info@addi-data.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*/
|
||||
|
||||
/* Card Specific information */
|
||||
#define APCI035_BOARD_VENDOR_ID 0x15B8
|
||||
#define APCI035_ADDRESS_RANGE 255
|
||||
|
||||
INT i_TW_Number;
|
||||
struct {
|
||||
INT i_Gain;
|
||||
INT i_Polarity;
|
||||
INT i_OffsetRange;
|
||||
INT i_Coupling;
|
||||
INT i_SingleDiff;
|
||||
INT i_AutoCalibration;
|
||||
UINT ui_ReloadValue;
|
||||
UINT ui_TimeUnitReloadVal;
|
||||
INT i_Interrupt;
|
||||
INT i_ModuleSelection;
|
||||
} Config_Parameters_Main;
|
||||
|
||||
/* ANALOG INPUT RANGE */
|
||||
struct comedi_lrange range_apci035_ai = { 8, {
|
||||
BIP_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(2),
|
||||
BIP_RANGE(1),
|
||||
UNI_RANGE(10),
|
||||
UNI_RANGE(5),
|
||||
UNI_RANGE(2),
|
||||
UNI_RANGE(1)
|
||||
}
|
||||
};
|
||||
|
||||
/* Timer / Watchdog Related Defines */
|
||||
#define APCI035_TCW_SYNC_ENABLEDISABLE 0
|
||||
#define APCI035_TCW_RELOAD_VALUE 4
|
||||
#define APCI035_TCW_TIMEBASE 8
|
||||
#define APCI035_TCW_PROG 12
|
||||
#define APCI035_TCW_TRIG_STATUS 16
|
||||
#define APCI035_TCW_IRQ 20
|
||||
#define APCI035_TCW_WARN_TIMEVAL 24
|
||||
#define APCI035_TCW_WARN_TIMEBASE 28
|
||||
|
||||
#define ADDIDATA_TIMER 0
|
||||
/* #define ADDIDATA_WATCHDOG 1 */
|
||||
|
||||
#define APCI035_TW1 0
|
||||
#define APCI035_TW2 32
|
||||
#define APCI035_TW3 64
|
||||
#define APCI035_TW4 96
|
||||
|
||||
#define APCI035_AI_OFFSET 0
|
||||
#define APCI035_TEMP 128
|
||||
#define APCI035_ALR_SEQ 4
|
||||
#define APCI035_START_STOP_INDEX 8
|
||||
#define APCI035_ALR_START_STOP 12
|
||||
#define APCI035_ALR_IRQ 16
|
||||
#define APCI035_EOS 20
|
||||
#define APCI035_CHAN_NO 24
|
||||
#define APCI035_CHAN_VAL 28
|
||||
#define APCI035_CONV_TIME_TIME_BASE 36
|
||||
#define APCI035_RELOAD_CONV_TIME_VAL 32
|
||||
#define APCI035_DELAY_TIME_TIME_BASE 44
|
||||
#define APCI035_RELOAD_DELAY_TIME_VAL 40
|
||||
#define ENABLE_EXT_TRIG 1
|
||||
#define ENABLE_EXT_GATE 2
|
||||
#define ENABLE_EXT_TRIG_GATE 3
|
||||
|
||||
#define ANALOG_INPUT 0
|
||||
#define TEMPERATURE 1
|
||||
#define RESISTANCE 2
|
||||
|
||||
#define ADDIDATA_GREATER_THAN_TEST 0
|
||||
#define ADDIDATA_LESS_THAN_TEST 1
|
||||
|
||||
#define APCI035_MAXVOLT 2.5
|
||||
|
||||
#define ADDIDATA_UNIPOLAR 1
|
||||
#define ADDIDATA_BIPOLAR 2
|
||||
|
||||
/* ADDIDATA Enable Disable */
|
||||
#define ADDIDATA_ENABLE 1
|
||||
#define ADDIDATA_DISABLE 0
|
||||
|
||||
/* Hardware Layer functions for Apci035 */
|
||||
|
||||
/* TIMER */
|
||||
/* timer value is passed as u seconds */
|
||||
INT i_APCI035_ConfigTimerWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
INT i_APCI035_StartStopWriteTimerWatchdog(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
INT i_APCI035_ReadTimerWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
/* Temperature Related Defines (Analog Input Subdevice) */
|
||||
|
||||
INT i_APCI035_ConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
INT i_APCI035_ReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
/* Interrupt */
|
||||
static void v_APCI035_Interrupt(int irq, void *d);
|
||||
|
||||
/* Reset functions */
|
||||
INT i_APCI035_Reset(struct comedi_device *dev);
|
|
@ -0,0 +1,285 @@
|
|||
/**
|
||||
@verbatim
|
||||
|
||||
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
|
||||
ADDI-DATA GmbH
|
||||
Dieselstrasse 3
|
||||
D-77833 Ottersweier
|
||||
Tel: +19(0)7223/9493-0
|
||||
Fax: +49(0)7223/9493-92
|
||||
http://www.addi-data-com
|
||||
info@addi-data.com
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
You shoud also find the complete GPL in the COPYING file accompanying this source code.
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
/*
|
||||
|
||||
+-----------------------------------------------------------------------+
|
||||
| (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
|
||||
+-----------------------------------------------------------------------+
|
||||
| Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
|
||||
| Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
|
||||
+-------------------------------+---------------------------------------+
|
||||
| Project : APCI-1032 | Compiler : GCC |
|
||||
| Module name : hwdrv_apci1032.c| Version : 2.96 |
|
||||
+-------------------------------+---------------------------------------+
|
||||
| Project manager: Eric Stolz | Date : 02/12/2002 |
|
||||
+-------------------------------+---------------------------------------+
|
||||
| Description : Hardware Layer Acces For APCI-1032 |
|
||||
+-----------------------------------------------------------------------+
|
||||
| UPDATES |
|
||||
+----------+-----------+------------------------------------------------+
|
||||
| Date | Author | Description of updates |
|
||||
+----------+-----------+------------------------------------------------+
|
||||
| | | |
|
||||
| | | |
|
||||
| | | |
|
||||
+----------+-----------+------------------------------------------------+
|
||||
*/
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Included files |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
#include "hwdrv_apci1032.h"
|
||||
#include <linux/delay.h>
|
||||
//Global variables
|
||||
UINT ui_InterruptStatus = 0;
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI1032_ConfigDigitalInput |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s, |
|
||||
| struct comedi_insn *insn,unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Configures the digital input Subdevice |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| unsigned int *data : Data Pointer contains |
|
||||
| configuration parameters as below |
|
||||
| |
|
||||
| data[0] : 1 Enable Digital Input Interrupt |
|
||||
| 0 Disable Digital Input Interrupt |
|
||||
| data[1] : 0 ADDIDATA Interrupt OR LOGIC |
|
||||
| : 1 ADDIDATA Interrupt AND LOGIC |
|
||||
| data[2] : Interrupt mask for the mode 1 |
|
||||
| data[3] : Interrupt mask for the mode 2 |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
INT i_APCI1032_ConfigDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
UINT ui_TmpValue;
|
||||
|
||||
ULONG ul_Command1 = 0;
|
||||
ULONG ul_Command2 = 0;
|
||||
devpriv->tsk_Current = current;
|
||||
|
||||
/*******************************/
|
||||
/* Set the digital input logic */
|
||||
/*******************************/
|
||||
if (data[0] == ADDIDATA_ENABLE) {
|
||||
ul_Command1 = ul_Command1 | data[2];
|
||||
ul_Command2 = ul_Command2 | data[3];
|
||||
outl(ul_Command1,
|
||||
devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1);
|
||||
outl(ul_Command2,
|
||||
devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE2);
|
||||
if (data[1] == ADDIDATA_OR) {
|
||||
outl(0x4, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
|
||||
ui_TmpValue =
|
||||
inl(devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
|
||||
} //if (data[1] == ADDIDATA_OR)
|
||||
else {
|
||||
outl(0x6, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
|
||||
} //else if(data[1] == ADDIDATA_OR)
|
||||
} // if( data[0] == ADDIDATA_ENABLE)
|
||||
else {
|
||||
ul_Command1 = ul_Command1 & 0xFFFF0000;
|
||||
ul_Command2 = ul_Command2 & 0xFFFF0000;
|
||||
outl(ul_Command1,
|
||||
devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1);
|
||||
outl(ul_Command2,
|
||||
devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE2);
|
||||
outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
|
||||
} //else if ( data[0] == ADDIDATA_ENABLE)
|
||||
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI1032_Read1DigitalInput |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s, |
|
||||
| struct comedi_insn *insn,unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Return the status of the digital input |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| UINT ui_Channel : Channel number to read |
|
||||
| unsigned int *data : Data Pointer to read status |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
INT i_APCI1032_Read1DigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
UINT ui_TmpValue = 0;
|
||||
UINT ui_Channel;
|
||||
ui_Channel = CR_CHAN(insn->chanspec);
|
||||
if (ui_Channel >= 0 && ui_Channel <= 31) {
|
||||
ui_TmpValue = (UINT) inl(devpriv->iobase + APCI1032_DIGITAL_IP);
|
||||
// since only 1 channel reqd to bring it to last bit it is rotated
|
||||
// 8 +(chan - 1) times then ANDed with 1 for last bit.
|
||||
*data = (ui_TmpValue >> ui_Channel) & 0x1;
|
||||
} //if(ui_Channel >= 0 && ui_Channel <=31)
|
||||
else {
|
||||
//comedi_error(dev," \n chan spec wrong\n");
|
||||
return -EINVAL; // "sorry channel spec wrong "
|
||||
} //else if(ui_Channel >= 0 && ui_Channel <=31)
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI1032_ReadMoreDigitalInput |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s, |
|
||||
| struct comedi_insn *insn,unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Return the status of the Requested digital inputs |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| UINT ui_NoOfChannels : No Of Channels To be Read |
|
||||
| UINT *data : Data Pointer to read status |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
INT i_APCI1032_ReadMoreDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
UINT ui_PortValue = data[0];
|
||||
UINT ui_Mask = 0;
|
||||
UINT ui_NoOfChannels;
|
||||
|
||||
ui_NoOfChannels = CR_CHAN(insn->chanspec);
|
||||
if (data[1] == 0) {
|
||||
*data = (UINT) inl(devpriv->iobase + APCI1032_DIGITAL_IP);
|
||||
switch (ui_NoOfChannels) {
|
||||
case 2:
|
||||
ui_Mask = 3;
|
||||
*data = (*data >> (2 * ui_PortValue)) & ui_Mask;
|
||||
break;
|
||||
case 4:
|
||||
ui_Mask = 15;
|
||||
*data = (*data >> (4 * ui_PortValue)) & ui_Mask;
|
||||
break;
|
||||
case 8:
|
||||
ui_Mask = 255;
|
||||
*data = (*data >> (8 * ui_PortValue)) & ui_Mask;
|
||||
break;
|
||||
case 16:
|
||||
ui_Mask = 65535;
|
||||
*data = (*data >> (16 * ui_PortValue)) & ui_Mask;
|
||||
break;
|
||||
case 31:
|
||||
break;
|
||||
default:
|
||||
//comedi_error(dev," \nchan spec wrong\n");
|
||||
return -EINVAL; // "sorry channel spec wrong "
|
||||
break;
|
||||
} //switch(ui_NoOfChannels)
|
||||
} //if(data[1]==0)
|
||||
else {
|
||||
if (data[1] == 1) {
|
||||
*data = ui_InterruptStatus;
|
||||
} //if(data[1]==1)
|
||||
} //else if(data[1]==0)
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : static void v_APCI1032_Interrupt |
|
||||
| (int irq , void *d) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Interrupt handler for the interruptible digital inputs |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : int irq : irq number |
|
||||
| void *d : void pointer |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
static void v_APCI1032_Interrupt(int irq, void *d)
|
||||
{
|
||||
struct comedi_device *dev = d;
|
||||
|
||||
UINT ui_Temp;
|
||||
//disable the interrupt
|
||||
ui_Temp = inl(devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
|
||||
outl(ui_Temp & APCI1032_DIGITAL_IP_INTERRUPT_DISABLE,
|
||||
devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
|
||||
ui_InterruptStatus =
|
||||
inl(devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_STATUS);
|
||||
ui_InterruptStatus = ui_InterruptStatus & 0X0000FFFF;
|
||||
send_sig(SIGIO, devpriv->tsk_Current, 0); // send signal to the sample
|
||||
outl(ui_Temp, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); //enable the interrupt
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI1032_Reset(struct comedi_device *dev) | |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task :resets all the registers |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
INT i_APCI1032_Reset(struct comedi_device * dev)
|
||||
{
|
||||
outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); //disable the interrupts
|
||||
inl(devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_STATUS); //Reset the interrupt status register
|
||||
outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1); //Disable the and/or interrupt
|
||||
outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE2);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
*
|
||||
* ADDI-DATA GmbH
|
||||
* Dieselstrasse 3
|
||||
* D-77833 Ottersweier
|
||||
* Tel: +19(0)7223/9493-0
|
||||
* Fax: +49(0)7223/9493-92
|
||||
* http://www.addi-data-com
|
||||
* info@addi-data.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*/
|
||||
|
||||
/********* Definitions for APCI-1032 card *****/
|
||||
|
||||
#define APCI1032_BOARD_VENDOR_ID 0x15B8
|
||||
#define APCI1032_ADDRESS_RANGE 20
|
||||
//DIGITAL INPUT DEFINE
|
||||
|
||||
#define APCI1032_DIGITAL_IP 0
|
||||
#define APCI1032_DIGITAL_IP_INTERRUPT_MODE1 4
|
||||
#define APCI1032_DIGITAL_IP_INTERRUPT_MODE2 8
|
||||
#define APCI1032_DIGITAL_IP_IRQ 16
|
||||
|
||||
//Digital Input IRQ Function Selection
|
||||
#define ADDIDATA_OR 0
|
||||
#define ADDIDATA_AND 1
|
||||
|
||||
//Digital Input Interrupt Status
|
||||
#define APCI1032_DIGITAL_IP_INTERRUPT_STATUS 12
|
||||
|
||||
//Digital Input Interrupt Enable Disable.
|
||||
#define APCI1032_DIGITAL_IP_INTERRUPT_ENABLE 0x4
|
||||
#define APCI1032_DIGITAL_IP_INTERRUPT_DISABLE 0xFFFFFFFB
|
||||
|
||||
//ADDIDATA Enable Disable
|
||||
|
||||
#define ADDIDATA_ENABLE 1
|
||||
#define ADDIDATA_DISABLE 0
|
||||
|
||||
// Hardware Layer functions for Apci1032
|
||||
|
||||
//DI
|
||||
// for di read
|
||||
|
||||
INT i_APCI1032_ConfigDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
INT i_APCI1032_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
INT i_APCI1032_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
// Interrupt functions.....
|
||||
|
||||
static void v_APCI1032_Interrupt(int irq, void *d);
|
||||
//Reset
|
||||
INT i_APCI1032_Reset(struct comedi_device *dev);
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
* Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
*
|
||||
* ADDI-DATA GmbH
|
||||
* Dieselstrasse 3
|
||||
* D-77833 Ottersweier
|
||||
* Tel: +19(0)7223/9493-0
|
||||
* Fax: +49(0)7223/9493-92
|
||||
* http://www.addi-data-com
|
||||
* info@addi-data.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*/
|
||||
|
||||
/********* Definitions for APCI-1500 card *****/
|
||||
|
||||
// Card Specific information
|
||||
#define APCI1500_BOARD_VENDOR_ID 0x10e8
|
||||
#define APCI1500_ADDRESS_RANGE 4
|
||||
|
||||
//DIGITAL INPUT-OUTPUT DEFINE
|
||||
|
||||
#define APCI1500_DIGITAL_OP 2
|
||||
#define APCI1500_DIGITAL_IP 0
|
||||
#define APCI1500_AND 2
|
||||
#define APCI1500_OR 4
|
||||
#define APCI1500_OR_PRIORITY 6
|
||||
#define APCI1500_CLK_SELECT 0
|
||||
#define COUNTER1 0
|
||||
#define COUNTER2 1
|
||||
#define COUNTER3 2
|
||||
#define APCI1500_COUNTER 0x20
|
||||
#define APCI1500_TIMER 0
|
||||
#define APCI1500_WATCHDOG 0
|
||||
#define APCI1500_SINGLE 0
|
||||
#define APCI1500_CONTINUOUS 0x80
|
||||
#define APCI1500_DISABLE 0
|
||||
#define APCI1500_ENABLE 1
|
||||
#define APCI1500_SOFTWARE_TRIGGER 0x4
|
||||
#define APCI1500_HARDWARE_TRIGGER 0x10
|
||||
#define APCI1500_SOFTWARE_GATE 0
|
||||
#define APCI1500_HARDWARE_GATE 0x8
|
||||
#define START 0
|
||||
#define STOP 1
|
||||
#define TRIGGER 2
|
||||
|
||||
/*
|
||||
* Zillog I/O enumeration
|
||||
*/
|
||||
enum {
|
||||
APCI1500_Z8536_PORT_C,
|
||||
APCI1500_Z8536_PORT_B,
|
||||
APCI1500_Z8536_PORT_A,
|
||||
APCI1500_Z8536_CONTROL_REGISTER
|
||||
};
|
||||
|
||||
/*
|
||||
* Z8536 CIO Internal Address
|
||||
*/
|
||||
enum {
|
||||
APCI1500_RW_MASTER_INTERRUPT_CONTROL,
|
||||
APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
|
||||
APCI1500_RW_PORT_A_INTERRUPT_CONTROL,
|
||||
APCI1500_RW_PORT_B_INTERRUPT_CONTROL,
|
||||
APCI1500_RW_TIMER_COUNTER_INTERRUPT_VECTOR,
|
||||
APCI1500_RW_PORT_C_DATA_PCITCH_POLARITY,
|
||||
APCI1500_RW_PORT_C_DATA_DIRECTION,
|
||||
APCI1500_RW_PORT_C_SPECIAL_IO_CONTROL,
|
||||
|
||||
APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
|
||||
APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
|
||||
APCI1500_RW_CPT_TMR1_CMD_STATUS,
|
||||
APCI1500_RW_CPT_TMR2_CMD_STATUS,
|
||||
APCI1500_RW_CPT_TMR3_CMD_STATUS,
|
||||
APCI1500_RW_PORT_A_DATA,
|
||||
APCI1500_RW_PORT_B_DATA,
|
||||
APCI1500_RW_PORT_C_DATA,
|
||||
|
||||
APCI1500_R_CPT_TMR1_VALUE_HIGH,
|
||||
APCI1500_R_CPT_TMR1_VALUE_LOW,
|
||||
APCI1500_R_CPT_TMR2_VALUE_HIGH,
|
||||
APCI1500_R_CPT_TMR2_VALUE_LOW,
|
||||
APCI1500_R_CPT_TMR3_VALUE_HIGH,
|
||||
APCI1500_R_CPT_TMR3_VALUE_LOW,
|
||||
APCI1500_RW_CPT_TMR1_TIME_CST_HIGH,
|
||||
APCI1500_RW_CPT_TMR1_TIME_CST_LOW,
|
||||
APCI1500_RW_CPT_TMR2_TIME_CST_HIGH,
|
||||
APCI1500_RW_CPT_TMR2_TIME_CST_LOW,
|
||||
APCI1500_RW_CPT_TMR3_TIME_CST_HIGH,
|
||||
APCI1500_RW_CPT_TMR3_TIME_CST_LOW,
|
||||
APCI1500_RW_CPT_TMR1_MODE_SPECIFICATION,
|
||||
APCI1500_RW_CPT_TMR2_MODE_SPECIFICATION,
|
||||
APCI1500_RW_CPT_TMR3_MODE_SPECIFICATION,
|
||||
APCI1500_R_CURRENT_VECTOR,
|
||||
|
||||
APCI1500_RW_PORT_A_SPECIFICATION,
|
||||
APCI1500_RW_PORT_A_HANDSHAKE_SPECIFICATION,
|
||||
APCI1500_RW_PORT_A_DATA_PCITCH_POLARITY,
|
||||
APCI1500_RW_PORT_A_DATA_DIRECTION,
|
||||
APCI1500_RW_PORT_A_SPECIAL_IO_CONTROL,
|
||||
APCI1500_RW_PORT_A_PATTERN_POLARITY,
|
||||
APCI1500_RW_PORT_A_PATTERN_TRANSITION,
|
||||
APCI1500_RW_PORT_A_PATTERN_MASK,
|
||||
|
||||
APCI1500_RW_PORT_B_SPECIFICATION,
|
||||
APCI1500_RW_PORT_B_HANDSHAKE_SPECIFICATION,
|
||||
APCI1500_RW_PORT_B_DATA_PCITCH_POLARITY,
|
||||
APCI1500_RW_PORT_B_DATA_DIRECTION,
|
||||
APCI1500_RW_PORT_B_SPECIAL_IO_CONTROL,
|
||||
APCI1500_RW_PORT_B_PATTERN_POLARITY,
|
||||
APCI1500_RW_PORT_B_PATTERN_TRANSITION,
|
||||
APCI1500_RW_PORT_B_PATTERN_MASK
|
||||
};
|
||||
|
||||
/*----------DIGITAL INPUT----------------*/
|
||||
static int i_APCI1500_Initialisation(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int i_APCI1500_ConfigDigitalInputEvent(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
|
||||
static int i_APCI1500_StartStopInputEvent(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int i_APCI1500_ReadMoreDigitalInput(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
/*---------- DIGITAL OUTPUT------------*/
|
||||
static int i_APCI1500_ConfigDigitalOutputErrorInterrupt(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
static int i_APCI1500_WriteDigitalOutput(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
/*----------TIMER----------------*/
|
||||
static int i_APCI1500_ConfigCounterTimerWatchdog(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
static int i_APCI1500_StartStopTriggerTimerCounterWatchdog(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
static int i_APCI1500_ReadCounterTimerWatchdog(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
static int i_APCI1500_ReadInterruptMask(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
/*----------INTERRUPT HANDLER------*/
|
||||
static void v_APCI1500_Interrupt(int irq, void *d);
|
||||
static int i_APCI1500_ConfigureInterrupt(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
/*----------RESET---------------*/
|
||||
static int i_APCI1500_Reset(struct comedi_device *dev);
|
|
@ -0,0 +1,542 @@
|
|||
/**
|
||||
@verbatim
|
||||
|
||||
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
|
||||
ADDI-DATA GmbH
|
||||
Dieselstrasse 3
|
||||
D-77833 Ottersweier
|
||||
Tel: +19(0)7223/9493-0
|
||||
Fax: +49(0)7223/9493-92
|
||||
http://www.addi-data-com
|
||||
info@addi-data.com
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
You shoud also find the complete GPL in the COPYING file accompanying this source code.
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
/*
|
||||
|
||||
+-----------------------------------------------------------------------+
|
||||
| (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
|
||||
+-----------------------------------------------------------------------+
|
||||
| Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
|
||||
| Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
|
||||
+-------------------------------+---------------------------------------+
|
||||
| Project : APCI-1516 | Compiler : GCC |
|
||||
| Module name : hwdrv_apci1516.c| Version : 2.96 |
|
||||
+-------------------------------+---------------------------------------+
|
||||
| Project manager: Eric Stolz | Date : 02/12/2002 |
|
||||
+-------------------------------+---------------------------------------+
|
||||
| Description : Hardware Layer Acces For APCI-1516 |
|
||||
+-----------------------------------------------------------------------+
|
||||
| UPDATES |
|
||||
+----------+-----------+------------------------------------------------+
|
||||
| Date | Author | Description of updates |
|
||||
+----------+-----------+------------------------------------------------+
|
||||
| | | |
|
||||
| | | |
|
||||
| | | |
|
||||
+----------+-----------+------------------------------------------------+
|
||||
*/
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Included files |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
#include "hwdrv_apci1516.h"
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI1516_Read1DigitalInput |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s, |
|
||||
| struct comedi_insn *insn,unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Return the status of the digital input |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| struct comedi_subdevice *s, :pointer to subdevice structure
|
||||
struct comedi_insn *insn :pointer to insn structure |
|
||||
| unsigned int *data : Data Pointer to read status |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
INT i_APCI1516_Read1DigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
UINT ui_TmpValue = 0;
|
||||
UINT ui_Channel;
|
||||
ui_Channel = CR_CHAN(insn->chanspec);
|
||||
if (ui_Channel >= 0 && ui_Channel <= 7) {
|
||||
ui_TmpValue = (UINT) inw(devpriv->iobase + APCI1516_DIGITAL_IP);
|
||||
// since only 1 channel reqd to bring it to last bit it is rotated
|
||||
// 8 +(chan - 1) times then ANDed with 1 for last bit.
|
||||
*data = (ui_TmpValue >> ui_Channel) & 0x1;
|
||||
} //if(ui_Channel >= 0 && ui_Channel <=7)
|
||||
else {
|
||||
//comedi_error(dev," \n chan spec wrong\n");
|
||||
return -EINVAL; // "sorry channel spec wrong "
|
||||
} //else if(ui_Channel >= 0 && ui_Channel <=7)
|
||||
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI1516_ReadMoreDigitalInput |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s, |
|
||||
| struct comedi_insn *insn,unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Return the status of the Requested digital inputs |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| struct comedi_subdevice *s, :pointer to subdevice structure
|
||||
struct comedi_insn *insn :pointer to insn structure |
|
||||
| unsigned int *data : Data Pointer to read status |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
INT i_APCI1516_ReadMoreDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
|
||||
UINT ui_PortValue = data[0];
|
||||
UINT ui_Mask = 0;
|
||||
UINT ui_NoOfChannels;
|
||||
|
||||
ui_NoOfChannels = CR_CHAN(insn->chanspec);
|
||||
|
||||
*data = (UINT) inw(devpriv->iobase + APCI1516_DIGITAL_IP);
|
||||
switch (ui_NoOfChannels) {
|
||||
case 2:
|
||||
ui_Mask = 3;
|
||||
*data = (*data >> (2 * ui_PortValue)) & ui_Mask;
|
||||
break;
|
||||
case 4:
|
||||
ui_Mask = 15;
|
||||
*data = (*data >> (4 * ui_PortValue)) & ui_Mask;
|
||||
break;
|
||||
case 7:
|
||||
break;
|
||||
|
||||
default:
|
||||
printk("\nWrong parameters\n");
|
||||
return -EINVAL; // "sorry channel spec wrong "
|
||||
break;
|
||||
} //switch(ui_NoOfChannels)
|
||||
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI1516_ConfigDigitalOutput (struct comedi_device *dev,
|
||||
struct comedi_subdevice *s struct comedi_insn *insn,unsigned int *data) |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Configures The Digital Output Subdevice. |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| unsigned int *data : Data Pointer contains |
|
||||
| configuration parameters as below |
|
||||
| struct comedi_subdevice *s, :pointer to subdevice structure
|
||||
struct comedi_insn *insn :pointer to insn structure |
|
||||
| data[0] :1:Memory on |
|
||||
| 0:Memory off |
|
||||
| |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
int i_APCI1516_ConfigDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
devpriv->b_OutputMemoryStatus = data[0];
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI1516_WriteDigitalOutput |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
|
||||
unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Writes port value To the selected port |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| struct comedi_subdevice *s, :pointer to subdevice structure
|
||||
struct comedi_insn *insn :pointer to insn structure |
|
||||
| unsigned int *data : Data Pointer to read status |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
INT i_APCI1516_WriteDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
UINT ui_Temp, ui_Temp1;
|
||||
UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
|
||||
|
||||
printk("EL311003 : @=%x\n", devpriv->iobase + APCI1516_DIGITAL_OP);
|
||||
|
||||
if (devpriv->b_OutputMemoryStatus) {
|
||||
ui_Temp = inw(devpriv->iobase + APCI1516_DIGITAL_OP);
|
||||
|
||||
} //if(devpriv->b_OutputMemoryStatus )
|
||||
else {
|
||||
ui_Temp = 0;
|
||||
} //if(devpriv->b_OutputMemoryStatus )
|
||||
if (data[3] == 0) {
|
||||
if (data[1] == 0) {
|
||||
data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
|
||||
outw(data[0], devpriv->iobase + APCI1516_DIGITAL_OP);
|
||||
|
||||
printk("EL311003 : d=%d @=%x\n", data[0],
|
||||
devpriv->iobase + APCI1516_DIGITAL_OP);
|
||||
|
||||
} //if(data[1]==0)
|
||||
else {
|
||||
if (data[1] == 1) {
|
||||
switch (ui_NoOfChannel) {
|
||||
|
||||
case 2:
|
||||
data[0] =
|
||||
(data[0] << (2 *
|
||||
data[2])) | ui_Temp;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
data[0] =
|
||||
(data[0] << (4 *
|
||||
data[2])) | ui_Temp;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
data[0] = data[0] | ui_Temp;
|
||||
break;
|
||||
|
||||
default:
|
||||
comedi_error(dev, " chan spec wrong");
|
||||
return -EINVAL; // "sorry channel spec wrong "
|
||||
|
||||
} //switch(ui_NoOfChannels)
|
||||
|
||||
outw(data[0],
|
||||
devpriv->iobase + APCI1516_DIGITAL_OP);
|
||||
|
||||
printk("EL311003 : d=%d @=%x\n", data[0],
|
||||
devpriv->iobase + APCI1516_DIGITAL_OP);
|
||||
} // if(data[1]==1)
|
||||
else {
|
||||
printk("\nSpecified channel not supported\n");
|
||||
} //else if(data[1]==1)
|
||||
} //elseif(data[1]==0)
|
||||
} //if(data[3]==0)
|
||||
else {
|
||||
if (data[3] == 1) {
|
||||
if (data[1] == 0) {
|
||||
data[0] = ~data[0] & 0x1;
|
||||
ui_Temp1 = 1;
|
||||
ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
|
||||
ui_Temp = ui_Temp | ui_Temp1;
|
||||
data[0] = (data[0] << ui_NoOfChannel) ^ 0xff;
|
||||
data[0] = data[0] & ui_Temp;
|
||||
outw(data[0],
|
||||
devpriv->iobase + APCI1516_DIGITAL_OP);
|
||||
|
||||
printk("EL311003 : d=%d @=%x\n", data[0],
|
||||
devpriv->iobase + APCI1516_DIGITAL_OP);
|
||||
|
||||
} //if(data[1]==0)
|
||||
else {
|
||||
if (data[1] == 1) {
|
||||
switch (ui_NoOfChannel) {
|
||||
|
||||
case 2:
|
||||
data[0] = ~data[0] & 0x3;
|
||||
ui_Temp1 = 3;
|
||||
ui_Temp1 =
|
||||
ui_Temp1 << 2 * data[2];
|
||||
ui_Temp = ui_Temp | ui_Temp1;
|
||||
data[0] =
|
||||
((data[0] << (2 *
|
||||
data
|
||||
[2])) ^
|
||||
0xff) & ui_Temp;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
data[0] = ~data[0] & 0xf;
|
||||
ui_Temp1 = 15;
|
||||
ui_Temp1 =
|
||||
ui_Temp1 << 4 * data[2];
|
||||
ui_Temp = ui_Temp | ui_Temp1;
|
||||
data[0] =
|
||||
((data[0] << (4 *
|
||||
data
|
||||
[2])) ^
|
||||
0xff) & ui_Temp;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
break;
|
||||
|
||||
default:
|
||||
comedi_error(dev,
|
||||
" chan spec wrong");
|
||||
return -EINVAL; // "sorry channel spec wrong "
|
||||
|
||||
} //switch(ui_NoOfChannels)
|
||||
|
||||
outw(data[0],
|
||||
devpriv->iobase +
|
||||
APCI1516_DIGITAL_OP);
|
||||
|
||||
printk("EL311003 : d=%d @=%x\n",
|
||||
data[0],
|
||||
devpriv->iobase +
|
||||
APCI1516_DIGITAL_OP);
|
||||
} // if(data[1]==1)
|
||||
else {
|
||||
printk("\nSpecified channel not supported\n");
|
||||
} //else if(data[1]==1)
|
||||
} //elseif(data[1]==0)
|
||||
} //if(data[3]==1);
|
||||
else {
|
||||
printk("\nSpecified functionality does not exist\n");
|
||||
return -EINVAL;
|
||||
} //if else data[3]==1)
|
||||
} //if else data[3]==0)
|
||||
return (insn->n);;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI1516_ReadDigitalOutput |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
|
||||
unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Read value of the selected channel or port |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| struct comedi_subdevice *s, :pointer to subdevice structure
|
||||
struct comedi_insn *insn :pointer to insn structure |
|
||||
| unsigned int *data : Data Pointer to read status |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
INT i_APCI1516_ReadDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
|
||||
UINT ui_Temp;
|
||||
UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
|
||||
ui_Temp = data[0];
|
||||
*data = inw(devpriv->iobase + APCI1516_DIGITAL_OP_RW);
|
||||
if (ui_Temp == 0) {
|
||||
*data = (*data >> ui_NoOfChannel) & 0x1;
|
||||
} //if(ui_Temp==0)
|
||||
else {
|
||||
if (ui_Temp == 1) {
|
||||
switch (ui_NoOfChannel) {
|
||||
|
||||
case 2:
|
||||
*data = (*data >> (2 * data[1])) & 3;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
*data = (*data >> (4 * data[1])) & 15;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
break;
|
||||
|
||||
default:
|
||||
comedi_error(dev, " chan spec wrong");
|
||||
return -EINVAL; // "sorry channel spec wrong "
|
||||
|
||||
} //switch(ui_NoOfChannels)
|
||||
} //if(ui_Temp==1)
|
||||
else {
|
||||
printk("\nSpecified channel not supported \n");
|
||||
} //elseif(ui_Temp==1)
|
||||
} //elseif(ui_Temp==0)
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI1516_ConfigWatchdog(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Configures The Watchdog |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| struct comedi_subdevice *s, :pointer to subdevice structure
|
||||
struct comedi_insn *insn :pointer to insn structure |
|
||||
| unsigned int *data : Data Pointer to read status |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
int i_APCI1516_ConfigWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
if (data[0] == 0) {
|
||||
//Disable the watchdog
|
||||
outw(0x0,
|
||||
devpriv->i_IobaseAddon +
|
||||
APCI1516_WATCHDOG_ENABLEDISABLE);
|
||||
//Loading the Reload value
|
||||
outw(data[1],
|
||||
devpriv->i_IobaseAddon +
|
||||
APCI1516_WATCHDOG_RELOAD_VALUE);
|
||||
data[1] = data[1] >> 16;
|
||||
outw(data[1],
|
||||
devpriv->i_IobaseAddon +
|
||||
APCI1516_WATCHDOG_RELOAD_VALUE + 2);
|
||||
} //if(data[0]==0)
|
||||
else {
|
||||
printk("\nThe input parameters are wrong\n");
|
||||
return -EINVAL;
|
||||
} //elseif(data[0]==0)
|
||||
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI1516_StartStopWriteWatchdog |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,unsigned int *data); |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Start / Stop The Watchdog |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| struct comedi_subdevice *s, :pointer to subdevice structure
|
||||
struct comedi_insn *insn :pointer to insn structure |
|
||||
| unsigned int *data : Data Pointer to read status |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
int i_APCI1516_StartStopWriteWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
switch (data[0]) {
|
||||
case 0: //stop the watchdog
|
||||
outw(0x0, devpriv->i_IobaseAddon + APCI1516_WATCHDOG_ENABLEDISABLE); //disable the watchdog
|
||||
break;
|
||||
case 1: //start the watchdog
|
||||
outw(0x0001,
|
||||
devpriv->i_IobaseAddon +
|
||||
APCI1516_WATCHDOG_ENABLEDISABLE);
|
||||
break;
|
||||
case 2: //Software trigger
|
||||
outw(0x0201,
|
||||
devpriv->i_IobaseAddon +
|
||||
APCI1516_WATCHDOG_ENABLEDISABLE);
|
||||
break;
|
||||
default:
|
||||
printk("\nSpecified functionality does not exist\n");
|
||||
return -EINVAL;
|
||||
} // switch(data[0])
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI1516_ReadWatchdog |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
|
||||
unsigned int *data); |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Read The Watchdog |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| struct comedi_subdevice *s, :pointer to subdevice structure
|
||||
struct comedi_insn *insn :pointer to insn structure |
|
||||
| unsigned int *data : Data Pointer to read status |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
int i_APCI1516_ReadWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
data[0] = inw(devpriv->i_IobaseAddon + APCI1516_WATCHDOG_STATUS) & 0x1;
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI1516_Reset(struct comedi_device *dev) | |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task :resets all the registers |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
INT i_APCI1516_Reset(struct comedi_device * dev)
|
||||
{
|
||||
outw(0x0, devpriv->iobase + APCI1516_DIGITAL_OP); //RESETS THE DIGITAL OUTPUTS
|
||||
outw(0x0, devpriv->i_IobaseAddon + APCI1516_WATCHDOG_ENABLEDISABLE);
|
||||
outw(0x0, devpriv->i_IobaseAddon + APCI1516_WATCHDOG_RELOAD_VALUE);
|
||||
outw(0x0, devpriv->i_IobaseAddon + APCI1516_WATCHDOG_RELOAD_VALUE + 2);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
*
|
||||
* ADDI-DATA GmbH
|
||||
* Dieselstrasse 3
|
||||
* D-77833 Ottersweier
|
||||
* Tel: +19(0)7223/9493-0
|
||||
* Fax: +49(0)7223/9493-92
|
||||
* http://www.addi-data-com
|
||||
* info@addi-data.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*/
|
||||
|
||||
/********* Definitions for APCI-1516 card *****/
|
||||
|
||||
// Card Specific information
|
||||
#define APCI1516_BOARD_VENDOR_ID 0x15B8
|
||||
#define APCI1516_ADDRESS_RANGE 8
|
||||
|
||||
//DIGITAL INPUT-OUTPUT DEFINE
|
||||
|
||||
#define APCI1516_DIGITAL_OP 4
|
||||
#define APCI1516_DIGITAL_OP_RW 4
|
||||
#define APCI1516_DIGITAL_IP 0
|
||||
|
||||
// TIMER COUNTER WATCHDOG DEFINES
|
||||
|
||||
#define ADDIDATA_WATCHDOG 2
|
||||
#define APCI1516_DIGITAL_OP_WATCHDOG 0
|
||||
#define APCI1516_WATCHDOG_ENABLEDISABLE 12
|
||||
#define APCI1516_WATCHDOG_RELOAD_VALUE 4
|
||||
#define APCI1516_WATCHDOG_STATUS 16
|
||||
|
||||
// Hardware Layer functions for Apci1516
|
||||
|
||||
//Digital Input
|
||||
INT i_APCI1516_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
INT i_APCI1516_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
//Digital Output
|
||||
int i_APCI1516_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
INT i_APCI1516_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
INT i_APCI1516_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
// TIMER
|
||||
// timer value is passed as u seconds
|
||||
int i_APCI1516_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
int i_APCI1516_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
int i_APCI1516_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
//reset
|
||||
INT i_APCI1516_Reset(struct comedi_device *dev);
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
*
|
||||
* ADDI-DATA GmbH
|
||||
* Dieselstrasse 3
|
||||
* D-77833 Ottersweier
|
||||
* Tel: +19(0)7223/9493-0
|
||||
* Fax: +49(0)7223/9493-92
|
||||
* http://www.addi-data-com
|
||||
* info@addi-data.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*/
|
||||
|
||||
/********* Definitions for APCI-1564 card *****/
|
||||
|
||||
#define APCI1564_BOARD_VENDOR_ID 0x15B8
|
||||
#define APCI1564_ADDRESS_RANGE 128
|
||||
|
||||
//DIGITAL INPUT-OUTPUT DEFINE
|
||||
// Input defines
|
||||
#define APCI1564_DIGITAL_IP 0x04
|
||||
#define APCI1564_DIGITAL_IP_INTERRUPT_MODE1 4
|
||||
#define APCI1564_DIGITAL_IP_INTERRUPT_MODE2 8
|
||||
#define APCI1564_DIGITAL_IP_IRQ 16
|
||||
|
||||
// Output defines
|
||||
#define APCI1564_DIGITAL_OP 0x18
|
||||
#define APCI1564_DIGITAL_OP_RW 0
|
||||
#define APCI1564_DIGITAL_OP_INTERRUPT 4
|
||||
#define APCI1564_DIGITAL_OP_IRQ 12
|
||||
|
||||
//Digital Input IRQ Function Selection
|
||||
#define ADDIDATA_OR 0
|
||||
#define ADDIDATA_AND 1
|
||||
|
||||
//Digital Input Interrupt Status
|
||||
#define APCI1564_DIGITAL_IP_INTERRUPT_STATUS 12
|
||||
|
||||
//Digital Output Interrupt Status
|
||||
#define APCI1564_DIGITAL_OP_INTERRUPT_STATUS 8
|
||||
|
||||
//Digital Input Interrupt Enable Disable.
|
||||
#define APCI1564_DIGITAL_IP_INTERRUPT_ENABLE 0x4
|
||||
#define APCI1564_DIGITAL_IP_INTERRUPT_DISABLE 0xFFFFFFFB
|
||||
|
||||
//Digital Output Interrupt Enable Disable.
|
||||
#define APCI1564_DIGITAL_OP_VCC_INTERRUPT_ENABLE 0x1
|
||||
#define APCI1564_DIGITAL_OP_VCC_INTERRUPT_DISABLE 0xFFFFFFFE
|
||||
#define APCI1564_DIGITAL_OP_CC_INTERRUPT_ENABLE 0x2
|
||||
#define APCI1564_DIGITAL_OP_CC_INTERRUPT_DISABLE 0xFFFFFFFD
|
||||
|
||||
//ADDIDATA Enable Disable
|
||||
|
||||
#define ADDIDATA_ENABLE 1
|
||||
#define ADDIDATA_DISABLE 0
|
||||
|
||||
// TIMER COUNTER WATCHDOG DEFINES
|
||||
|
||||
#define ADDIDATA_TIMER 0
|
||||
#define ADDIDATA_COUNTER 1
|
||||
#define ADDIDATA_WATCHDOG 2
|
||||
#define APCI1564_DIGITAL_OP_WATCHDOG 0x28
|
||||
#define APCI1564_TIMER 0x48
|
||||
#define APCI1564_COUNTER1 0x0
|
||||
#define APCI1564_COUNTER2 0x20
|
||||
#define APCI1564_COUNTER3 0x40
|
||||
#define APCI1564_COUNTER4 0x60
|
||||
#define APCI1564_TCW_SYNC_ENABLEDISABLE 0
|
||||
#define APCI1564_TCW_RELOAD_VALUE 4
|
||||
#define APCI1564_TCW_TIMEBASE 8
|
||||
#define APCI1564_TCW_PROG 12
|
||||
#define APCI1564_TCW_TRIG_STATUS 16
|
||||
#define APCI1564_TCW_IRQ 20
|
||||
#define APCI1564_TCW_WARN_TIMEVAL 24
|
||||
#define APCI1564_TCW_WARN_TIMEBASE 28
|
||||
|
||||
// Hardware Layer functions for Apci1564
|
||||
|
||||
//DI
|
||||
// for di read
|
||||
INT i_APCI1564_ConfigDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
INT i_APCI1564_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
INT i_APCI1564_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
//DO
|
||||
int i_APCI1564_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
INT i_APCI1564_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
INT i_APCI1564_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
int i_APCI1564_ReadInterruptStatus(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
// TIMER
|
||||
// timer value is passed as u seconds
|
||||
INT i_APCI1564_ConfigTimerCounterWatchdog(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
int i_APCI1564_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
int i_APCI1564_ReadTimerCounterWatchdog(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
// INTERRUPT
|
||||
static void v_APCI1564_Interrupt(int irq, void *d);
|
||||
|
||||
// RESET
|
||||
INT i_APCI1564_Reset(struct comedi_device *dev);
|
|
@ -0,0 +1,780 @@
|
|||
/**
|
||||
@verbatim
|
||||
|
||||
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
|
||||
ADDI-DATA GmbH
|
||||
Dieselstrasse 3
|
||||
D-77833 Ottersweier
|
||||
Tel: +19(0)7223/9493-0
|
||||
Fax: +49(0)7223/9493-92
|
||||
http://www.addi-data-com
|
||||
info@addi-data.com
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
You shoud also find the complete GPL in the COPYING file accompanying this source code.
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
/*
|
||||
|
||||
+-----------------------------------------------------------------------+
|
||||
| (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
|
||||
+-----------------------------------------------------------------------+
|
||||
| Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
|
||||
| Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
|
||||
+-----------------------------------------------------------------------+
|
||||
| Project : API APCI1648 | Compiler : gcc |
|
||||
| Module name : TTL.C | Version : 2.96 |
|
||||
+-------------------------------+---------------------------------------+
|
||||
| Project manager: S. Weber | Date : 25/05/2005 |
|
||||
+-----------------------------------------------------------------------+
|
||||
| Description : APCI-16XX TTL I/O module |
|
||||
| |
|
||||
| |
|
||||
+-----------------------------------------------------------------------+
|
||||
| UPDATES |
|
||||
+-----------------------------------------------------------------------+
|
||||
| Date | Author | Description of updates |
|
||||
+----------+-----------+------------------------------------------------+
|
||||
|25.05.2005| S.Weber | Creation |
|
||||
| | | |
|
||||
+-----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Included files |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include "hwdrv_apci16xx.h"
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : INT i_APCI16XX_InsnConfigInitTTLIO |
|
||||
| (struct comedi_device *dev, |
|
||||
| struct comedi_subdevice *s, |
|
||||
| struct comedi_insn *insn, |
|
||||
| unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task APCI16XX_TTL_INIT (using defaults) : |
|
||||
| Configure the TTL I/O operating mode from all ports |
|
||||
| You must calling this function be |
|
||||
| for you call any other function witch access of TTL. |
|
||||
| APCI16XX_TTL_INITDIRECTION(user inputs for direction) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : b_InitType = (BYTE) data[0]; |
|
||||
| b_Port0Mode = (BYTE) data[1]; |
|
||||
| b_Port1Mode = (BYTE) data[2]; |
|
||||
| b_Port2Mode = (BYTE) data[3]; |
|
||||
| b_Port3Mode = (BYTE) data[4]; |
|
||||
| ........ |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : - |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value :>0: No error |
|
||||
| -1: Port 0 mode selection is wrong |
|
||||
| -2: Port 1 mode selection is wrong |
|
||||
| -3: Port 2 mode selection is wrong |
|
||||
| -4: Port 3 mode selection is wrong |
|
||||
| -X: Port X-1 mode selection is wrong |
|
||||
| .... |
|
||||
| -100 : Config command error |
|
||||
| -101 : Data size error |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
int i_APCI16XX_InsnConfigInitTTLIO(struct comedi_device * dev,
|
||||
struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
INT i_ReturnValue = insn->n;
|
||||
BYTE b_Command = 0;
|
||||
BYTE b_Cpt = 0;
|
||||
BYTE b_NumberOfPort =
|
||||
(BYTE) (devpriv->ps_BoardInfo->i_NbrTTLChannel / 8);
|
||||
|
||||
/************************/
|
||||
/* Test the buffer size */
|
||||
/************************/
|
||||
|
||||
if (insn->n >= 1) {
|
||||
/*******************/
|
||||
/* Get the command */
|
||||
/* **************** */
|
||||
|
||||
b_Command = (BYTE) data[0];
|
||||
|
||||
/********************/
|
||||
/* Test the command */
|
||||
/********************/
|
||||
|
||||
if ((b_Command == APCI16XX_TTL_INIT) ||
|
||||
(b_Command == APCI16XX_TTL_INITDIRECTION) ||
|
||||
(b_Command == APCI16XX_TTL_OUTPUTMEMORY)) {
|
||||
/***************************************/
|
||||
/* Test the initialisation buffer size */
|
||||
/***************************************/
|
||||
|
||||
if ((b_Command == APCI16XX_TTL_INITDIRECTION)
|
||||
&& ((BYTE) (insn->n - 1) != b_NumberOfPort)) {
|
||||
/*******************/
|
||||
/* Data size error */
|
||||
/*******************/
|
||||
|
||||
printk("\nBuffer size error");
|
||||
i_ReturnValue = -101;
|
||||
}
|
||||
|
||||
if ((b_Command == APCI16XX_TTL_OUTPUTMEMORY)
|
||||
&& ((BYTE) (insn->n) != 2)) {
|
||||
/*******************/
|
||||
/* Data size error */
|
||||
/*******************/
|
||||
|
||||
printk("\nBuffer size error");
|
||||
i_ReturnValue = -101;
|
||||
}
|
||||
} else {
|
||||
/************************/
|
||||
/* Config command error */
|
||||
/************************/
|
||||
|
||||
printk("\nCommand selection error");
|
||||
i_ReturnValue = -100;
|
||||
}
|
||||
} else {
|
||||
/*******************/
|
||||
/* Data size error */
|
||||
/*******************/
|
||||
|
||||
printk("\nBuffer size error");
|
||||
i_ReturnValue = -101;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/* Test if no error occur and APCI16XX_TTL_INITDIRECTION command selected */
|
||||
/**************************************************************************/
|
||||
|
||||
if ((i_ReturnValue >= 0) && (b_Command == APCI16XX_TTL_INITDIRECTION)) {
|
||||
memset(devpriv->ul_TTLPortConfiguration, 0,
|
||||
sizeof(devpriv->ul_TTLPortConfiguration));
|
||||
|
||||
/*************************************/
|
||||
/* Test the port direction selection */
|
||||
/*************************************/
|
||||
|
||||
for (b_Cpt = 1;
|
||||
(b_Cpt <= b_NumberOfPort) && (i_ReturnValue >= 0);
|
||||
b_Cpt++) {
|
||||
/**********************/
|
||||
/* Test the direction */
|
||||
/**********************/
|
||||
|
||||
if ((data[b_Cpt] != 0) && (data[b_Cpt] != 0xFF)) {
|
||||
/************************/
|
||||
/* Port direction error */
|
||||
/************************/
|
||||
|
||||
printk("\nPort %d direction selection error",
|
||||
(INT) b_Cpt);
|
||||
i_ReturnValue = -(INT) b_Cpt;
|
||||
}
|
||||
|
||||
/**************************/
|
||||
/* Save the configuration */
|
||||
/**************************/
|
||||
|
||||
devpriv->ul_TTLPortConfiguration[(b_Cpt - 1) / 4] =
|
||||
devpriv->ul_TTLPortConfiguration[(b_Cpt -
|
||||
1) / 4] | (data[b_Cpt] << (8 * ((b_Cpt -
|
||||
1) % 4)));
|
||||
}
|
||||
}
|
||||
|
||||
/**************************/
|
||||
/* Test if no error occur */
|
||||
/**************************/
|
||||
|
||||
if (i_ReturnValue >= 0) {
|
||||
/***********************************/
|
||||
/* Test if TTL port initilaisation */
|
||||
/***********************************/
|
||||
|
||||
if ((b_Command == APCI16XX_TTL_INIT)
|
||||
|| (b_Command == APCI16XX_TTL_INITDIRECTION)) {
|
||||
/******************************/
|
||||
/* Set all port configuration */
|
||||
/******************************/
|
||||
|
||||
for (b_Cpt = 0; b_Cpt <= b_NumberOfPort; b_Cpt++) {
|
||||
if ((b_Cpt % 4) == 0) {
|
||||
/*************************/
|
||||
/* Set the configuration */
|
||||
/*************************/
|
||||
|
||||
outl(devpriv->
|
||||
ul_TTLPortConfiguration[b_Cpt /
|
||||
4],
|
||||
devpriv->iobase + 32 + b_Cpt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************/
|
||||
/* Test if output memory initialisation command */
|
||||
/************************************************/
|
||||
|
||||
if (b_Command == APCI16XX_TTL_OUTPUTMEMORY) {
|
||||
if (data[1]) {
|
||||
devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
|
||||
} else {
|
||||
devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
|
||||
}
|
||||
}
|
||||
|
||||
return (i_ReturnValue);
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| INPUT FUNCTIONS |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : INT i_APCI16XX_InsnBitsReadTTLIO |
|
||||
| (struct comedi_device *dev, |
|
||||
| struct comedi_subdevice *s, |
|
||||
| struct comedi_insn *insn, |
|
||||
| unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Read the status from selected TTL digital input |
|
||||
| (b_InputChannel) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Read the status from digital input port |
|
||||
| (b_SelectedPort) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : |
|
||||
| APCI16XX_TTL_READCHANNEL |
|
||||
| b_SelectedPort= CR_RANGE(insn->chanspec); |
|
||||
| b_InputChannel= CR_CHAN(insn->chanspec); |
|
||||
| b_ReadType = (BYTE) data[0]; |
|
||||
| |
|
||||
| APCI16XX_TTL_READPORT |
|
||||
| b_SelectedPort= CR_RANGE(insn->chanspec); |
|
||||
| b_ReadType = (BYTE) data[0]; |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : data[0] 0 : Channle is not active |
|
||||
| 1 : Channle is active |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : >0 : No error |
|
||||
| -100 : Config command error |
|
||||
| -101 : Data size error |
|
||||
| -102 : The selected TTL input port is wrong |
|
||||
| -103 : The selected TTL digital input is wrong |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
int i_APCI16XX_InsnBitsReadTTLIO(struct comedi_device * dev,
|
||||
struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
INT i_ReturnValue = insn->n;
|
||||
BYTE b_Command = 0;
|
||||
BYTE b_NumberOfPort =
|
||||
(BYTE) (devpriv->ps_BoardInfo->i_NbrTTLChannel / 8);
|
||||
BYTE b_SelectedPort = CR_RANGE(insn->chanspec);
|
||||
BYTE b_InputChannel = CR_CHAN(insn->chanspec);
|
||||
BYTE *pb_Status;
|
||||
DWORD dw_Status;
|
||||
|
||||
/************************/
|
||||
/* Test the buffer size */
|
||||
/************************/
|
||||
|
||||
if (insn->n >= 1) {
|
||||
/*******************/
|
||||
/* Get the command */
|
||||
/* **************** */
|
||||
|
||||
b_Command = (BYTE) data[0];
|
||||
|
||||
/********************/
|
||||
/* Test the command */
|
||||
/********************/
|
||||
|
||||
if ((b_Command == APCI16XX_TTL_READCHANNEL)
|
||||
|| (b_Command == APCI16XX_TTL_READPORT)) {
|
||||
/**************************/
|
||||
/* Test the selected port */
|
||||
/**************************/
|
||||
|
||||
if (b_SelectedPort < b_NumberOfPort) {
|
||||
/**********************/
|
||||
/* Test if input port */
|
||||
/**********************/
|
||||
|
||||
if (((devpriv->ul_TTLPortConfiguration
|
||||
[b_SelectedPort /
|
||||
4] >> (8 *
|
||||
(b_SelectedPort
|
||||
%
|
||||
4))) &
|
||||
0xFF) == 0) {
|
||||
/***************************/
|
||||
/* Test the channel number */
|
||||
/***************************/
|
||||
|
||||
if ((b_Command ==
|
||||
APCI16XX_TTL_READCHANNEL)
|
||||
&& (b_InputChannel > 7)) {
|
||||
/*******************************************/
|
||||
/* The selected TTL digital input is wrong */
|
||||
/*******************************************/
|
||||
|
||||
printk("\nChannel selection error");
|
||||
i_ReturnValue = -103;
|
||||
}
|
||||
} else {
|
||||
/****************************************/
|
||||
/* The selected TTL input port is wrong */
|
||||
/****************************************/
|
||||
|
||||
printk("\nPort selection error");
|
||||
i_ReturnValue = -102;
|
||||
}
|
||||
} else {
|
||||
/****************************************/
|
||||
/* The selected TTL input port is wrong */
|
||||
/****************************************/
|
||||
|
||||
printk("\nPort selection error");
|
||||
i_ReturnValue = -102;
|
||||
}
|
||||
} else {
|
||||
/************************/
|
||||
/* Config command error */
|
||||
/************************/
|
||||
|
||||
printk("\nCommand selection error");
|
||||
i_ReturnValue = -100;
|
||||
}
|
||||
} else {
|
||||
/*******************/
|
||||
/* Data size error */
|
||||
/*******************/
|
||||
|
||||
printk("\nBuffer size error");
|
||||
i_ReturnValue = -101;
|
||||
}
|
||||
|
||||
/**************************/
|
||||
/* Test if no error occur */
|
||||
/**************************/
|
||||
|
||||
if (i_ReturnValue >= 0) {
|
||||
pb_Status = (PBYTE) & data[0];
|
||||
|
||||
/*******************************/
|
||||
/* Get the digital inpu status */
|
||||
/*******************************/
|
||||
|
||||
dw_Status =
|
||||
inl(devpriv->iobase + 8 + ((b_SelectedPort / 4) * 4));
|
||||
dw_Status = (dw_Status >> (8 * (b_SelectedPort % 4))) & 0xFF;
|
||||
|
||||
/***********************/
|
||||
/* Save the port value */
|
||||
/***********************/
|
||||
|
||||
*pb_Status = (BYTE) dw_Status;
|
||||
|
||||
/***************************************/
|
||||
/* Test if read channel status command */
|
||||
/***************************************/
|
||||
|
||||
if (b_Command == APCI16XX_TTL_READCHANNEL) {
|
||||
*pb_Status = (*pb_Status >> b_InputChannel) & 1;
|
||||
}
|
||||
}
|
||||
|
||||
return (i_ReturnValue);
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : INT i_APCI16XX_InsnReadTTLIOAllPortValue |
|
||||
| (struct comedi_device *dev, |
|
||||
| struct comedi_subdevice *s, |
|
||||
| struct comedi_insn *insn, |
|
||||
| unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Read the status from all digital input ports |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : - |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : data[0] : Port 0 to 3 data |
|
||||
| data[1] : Port 4 to 7 data |
|
||||
| .... |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : 0: No error |
|
||||
| -100 : Read command error |
|
||||
| -101 : Data size error |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
int i_APCI16XX_InsnReadTTLIOAllPortValue(struct comedi_device * dev,
|
||||
struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
BYTE b_Command = (BYTE) CR_AREF(insn->chanspec);
|
||||
INT i_ReturnValue = insn->n;
|
||||
BYTE b_Cpt = 0;
|
||||
BYTE b_NumberOfPort = 0;
|
||||
unsigned int *pls_ReadData = data;
|
||||
|
||||
/********************/
|
||||
/* Test the command */
|
||||
/********************/
|
||||
|
||||
if ((b_Command == APCI16XX_TTL_READ_ALL_INPUTS)
|
||||
|| (b_Command == APCI16XX_TTL_READ_ALL_OUTPUTS)) {
|
||||
/**********************************/
|
||||
/* Get the number of 32-Bit ports */
|
||||
/**********************************/
|
||||
|
||||
b_NumberOfPort =
|
||||
(BYTE) (devpriv->ps_BoardInfo->i_NbrTTLChannel / 32);
|
||||
if ((b_NumberOfPort * 32) <
|
||||
devpriv->ps_BoardInfo->i_NbrTTLChannel) {
|
||||
b_NumberOfPort = b_NumberOfPort + 1;
|
||||
}
|
||||
|
||||
/************************/
|
||||
/* Test the buffer size */
|
||||
/************************/
|
||||
|
||||
if (insn->n >= b_NumberOfPort) {
|
||||
if (b_Command == APCI16XX_TTL_READ_ALL_INPUTS) {
|
||||
/**************************/
|
||||
/* Read all digital input */
|
||||
/**************************/
|
||||
|
||||
for (b_Cpt = 0; b_Cpt < b_NumberOfPort; b_Cpt++) {
|
||||
/************************/
|
||||
/* Read the 32-Bit port */
|
||||
/************************/
|
||||
|
||||
pls_ReadData[b_Cpt] =
|
||||
inl(devpriv->iobase + 8 +
|
||||
(b_Cpt * 4));
|
||||
|
||||
/**************************************/
|
||||
/* Mask all channels used als outputs */
|
||||
/**************************************/
|
||||
|
||||
pls_ReadData[b_Cpt] =
|
||||
pls_ReadData[b_Cpt] &
|
||||
(~devpriv->
|
||||
ul_TTLPortConfiguration[b_Cpt]);
|
||||
}
|
||||
} else {
|
||||
/****************************/
|
||||
/* Read all digital outputs */
|
||||
/****************************/
|
||||
|
||||
for (b_Cpt = 0; b_Cpt < b_NumberOfPort; b_Cpt++) {
|
||||
/************************/
|
||||
/* Read the 32-Bit port */
|
||||
/************************/
|
||||
|
||||
pls_ReadData[b_Cpt] =
|
||||
inl(devpriv->iobase + 20 +
|
||||
(b_Cpt * 4));
|
||||
|
||||
/**************************************/
|
||||
/* Mask all channels used als outputs */
|
||||
/**************************************/
|
||||
|
||||
pls_ReadData[b_Cpt] =
|
||||
pls_ReadData[b_Cpt] & devpriv->
|
||||
ul_TTLPortConfiguration[b_Cpt];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/*******************/
|
||||
/* Data size error */
|
||||
/*******************/
|
||||
|
||||
printk("\nBuffer size error");
|
||||
i_ReturnValue = -101;
|
||||
}
|
||||
} else {
|
||||
/*****************/
|
||||
/* Command error */
|
||||
/*****************/
|
||||
|
||||
printk("\nCommand selection error");
|
||||
i_ReturnValue = -100;
|
||||
}
|
||||
|
||||
return (i_ReturnValue);
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| OUTPUT FUNCTIONS |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : INT i_APCI16XX_InsnBitsWriteTTLIO |
|
||||
| (struct comedi_device *dev, |
|
||||
| struct comedi_subdevice *s, |
|
||||
| struct comedi_insn *insn, |
|
||||
| unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Set the state from selected TTL digital output |
|
||||
| (b_OutputChannel) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Set the state from digital output port |
|
||||
| (b_SelectedPort) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : |
|
||||
| APCI16XX_TTL_WRITECHANNEL_ON | APCI16XX_TTL_WRITECHANNEL_OFF |
|
||||
| b_SelectedPort = CR_RANGE(insn->chanspec); |
|
||||
| b_OutputChannel= CR_CHAN(insn->chanspec); |
|
||||
| b_Command = (BYTE) data[0]; |
|
||||
| |
|
||||
| APCI16XX_TTL_WRITEPORT_ON | APCI16XX_TTL_WRITEPORT_OFF |
|
||||
| b_SelectedPort = CR_RANGE(insn->chanspec); |
|
||||
| b_Command = (BYTE) data[0]; |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : data[0] : TTL output port 0 to 3 data |
|
||||
| data[1] : TTL output port 4 to 7 data |
|
||||
| .... |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : >0 : No error |
|
||||
| -100 : Command error |
|
||||
| -101 : Data size error |
|
||||
| -102 : The selected TTL output port is wrong |
|
||||
| -103 : The selected TTL digital output is wrong |
|
||||
| -104 : Output memory disabled |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
int i_APCI16XX_InsnBitsWriteTTLIO(struct comedi_device * dev,
|
||||
struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
INT i_ReturnValue = insn->n;
|
||||
BYTE b_Command = 0;
|
||||
BYTE b_NumberOfPort =
|
||||
(BYTE) (devpriv->ps_BoardInfo->i_NbrTTLChannel / 8);
|
||||
BYTE b_SelectedPort = CR_RANGE(insn->chanspec);
|
||||
BYTE b_OutputChannel = CR_CHAN(insn->chanspec);
|
||||
DWORD dw_Status = 0;
|
||||
|
||||
/************************/
|
||||
/* Test the buffer size */
|
||||
/************************/
|
||||
|
||||
if (insn->n >= 1) {
|
||||
/*******************/
|
||||
/* Get the command */
|
||||
/* **************** */
|
||||
|
||||
b_Command = (BYTE) data[0];
|
||||
|
||||
/********************/
|
||||
/* Test the command */
|
||||
/********************/
|
||||
|
||||
if ((b_Command == APCI16XX_TTL_WRITECHANNEL_ON) ||
|
||||
(b_Command == APCI16XX_TTL_WRITEPORT_ON) ||
|
||||
(b_Command == APCI16XX_TTL_WRITECHANNEL_OFF) ||
|
||||
(b_Command == APCI16XX_TTL_WRITEPORT_OFF)) {
|
||||
/**************************/
|
||||
/* Test the selected port */
|
||||
/**************************/
|
||||
|
||||
if (b_SelectedPort < b_NumberOfPort) {
|
||||
/***********************/
|
||||
/* Test if output port */
|
||||
/***********************/
|
||||
|
||||
if (((devpriv->ul_TTLPortConfiguration
|
||||
[b_SelectedPort /
|
||||
4] >> (8 *
|
||||
(b_SelectedPort
|
||||
%
|
||||
4))) &
|
||||
0xFF) == 0xFF) {
|
||||
/***************************/
|
||||
/* Test the channel number */
|
||||
/***************************/
|
||||
|
||||
if (((b_Command == APCI16XX_TTL_WRITECHANNEL_ON) || (b_Command == APCI16XX_TTL_WRITECHANNEL_OFF)) && (b_OutputChannel > 7)) {
|
||||
/********************************************/
|
||||
/* The selected TTL digital output is wrong */
|
||||
/********************************************/
|
||||
|
||||
printk("\nChannel selection error");
|
||||
i_ReturnValue = -103;
|
||||
}
|
||||
|
||||
if (((b_Command == APCI16XX_TTL_WRITECHANNEL_OFF) || (b_Command == APCI16XX_TTL_WRITEPORT_OFF)) && (devpriv->b_OutputMemoryStatus == ADDIDATA_DISABLE)) {
|
||||
/********************************************/
|
||||
/* The selected TTL digital output is wrong */
|
||||
/********************************************/
|
||||
|
||||
printk("\nOutput memory disabled");
|
||||
i_ReturnValue = -104;
|
||||
}
|
||||
|
||||
/************************/
|
||||
/* Test the buffer size */
|
||||
/************************/
|
||||
|
||||
if (((b_Command == APCI16XX_TTL_WRITEPORT_ON) || (b_Command == APCI16XX_TTL_WRITEPORT_OFF)) && (insn->n < 2)) {
|
||||
/*******************/
|
||||
/* Data size error */
|
||||
/*******************/
|
||||
|
||||
printk("\nBuffer size error");
|
||||
i_ReturnValue = -101;
|
||||
}
|
||||
} else {
|
||||
/*****************************************/
|
||||
/* The selected TTL output port is wrong */
|
||||
/*****************************************/
|
||||
|
||||
printk("\nPort selection error %lX",
|
||||
(unsigned long)devpriv->
|
||||
ul_TTLPortConfiguration[0]);
|
||||
i_ReturnValue = -102;
|
||||
}
|
||||
} else {
|
||||
/****************************************/
|
||||
/* The selected TTL output port is wrong */
|
||||
/****************************************/
|
||||
|
||||
printk("\nPort selection error %d %d",
|
||||
b_SelectedPort, b_NumberOfPort);
|
||||
i_ReturnValue = -102;
|
||||
}
|
||||
} else {
|
||||
/************************/
|
||||
/* Config command error */
|
||||
/************************/
|
||||
|
||||
printk("\nCommand selection error");
|
||||
i_ReturnValue = -100;
|
||||
}
|
||||
} else {
|
||||
/*******************/
|
||||
/* Data size error */
|
||||
/*******************/
|
||||
|
||||
printk("\nBuffer size error");
|
||||
i_ReturnValue = -101;
|
||||
}
|
||||
|
||||
/**************************/
|
||||
/* Test if no error occur */
|
||||
/**************************/
|
||||
|
||||
if (i_ReturnValue >= 0) {
|
||||
/********************************/
|
||||
/* Get the digital output state */
|
||||
/********************************/
|
||||
|
||||
dw_Status =
|
||||
inl(devpriv->iobase + 20 + ((b_SelectedPort / 4) * 4));
|
||||
|
||||
/**********************************/
|
||||
/* Test if output memory not used */
|
||||
/**********************************/
|
||||
|
||||
if (devpriv->b_OutputMemoryStatus == ADDIDATA_DISABLE) {
|
||||
/*********************************/
|
||||
/* Clear the selected port value */
|
||||
/*********************************/
|
||||
|
||||
dw_Status =
|
||||
dw_Status & (0xFFFFFFFFUL -
|
||||
(0xFFUL << (8 * (b_SelectedPort % 4))));
|
||||
}
|
||||
|
||||
/******************************/
|
||||
/* Test if setting channel ON */
|
||||
/******************************/
|
||||
|
||||
if (b_Command == APCI16XX_TTL_WRITECHANNEL_ON) {
|
||||
dw_Status =
|
||||
dw_Status | (1UL << ((8 * (b_SelectedPort %
|
||||
4)) + b_OutputChannel));
|
||||
}
|
||||
|
||||
/***************************/
|
||||
/* Test if setting port ON */
|
||||
/***************************/
|
||||
|
||||
if (b_Command == APCI16XX_TTL_WRITEPORT_ON) {
|
||||
dw_Status =
|
||||
dw_Status | ((data[1] & 0xFF) << (8 *
|
||||
(b_SelectedPort % 4)));
|
||||
}
|
||||
|
||||
/*******************************/
|
||||
/* Test if setting channel OFF */
|
||||
/*******************************/
|
||||
|
||||
if (b_Command == APCI16XX_TTL_WRITECHANNEL_OFF) {
|
||||
dw_Status =
|
||||
dw_Status & (0xFFFFFFFFUL -
|
||||
(1UL << ((8 * (b_SelectedPort % 4)) +
|
||||
b_OutputChannel)));
|
||||
}
|
||||
|
||||
/****************************/
|
||||
/* Test if setting port OFF */
|
||||
/****************************/
|
||||
|
||||
if (b_Command == APCI16XX_TTL_WRITEPORT_OFF) {
|
||||
dw_Status =
|
||||
dw_Status & (0xFFFFFFFFUL -
|
||||
((data[1] & 0xFF) << (8 * (b_SelectedPort %
|
||||
4))));
|
||||
}
|
||||
|
||||
outl(dw_Status,
|
||||
devpriv->iobase + 20 + ((b_SelectedPort / 4) * 4));
|
||||
}
|
||||
|
||||
return (i_ReturnValue);
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI2200_Reset(struct comedi_device *dev) | +----------------------------------------------------------------------------+
|
||||
| Task :resets all the registers |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : - |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : - |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
int i_APCI16XX_Reset(struct comedi_device * dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
*
|
||||
* ADDI-DATA GmbH
|
||||
* Dieselstrasse 3
|
||||
* D-77833 Ottersweier
|
||||
* Tel: +19(0)7223/9493-0
|
||||
* Fax: +49(0)7223/9493-92
|
||||
* http://www.addi-data-com
|
||||
* info@addi-data.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*/
|
||||
|
||||
#ifndef COMEDI_SUBD_TTLIO
|
||||
#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */
|
||||
#endif
|
||||
|
||||
#ifndef ADDIDATA_ENABLE
|
||||
#define ADDIDATA_ENABLE 1
|
||||
#define ADDIDATA_DISABLE 0
|
||||
#endif
|
||||
|
||||
#define APCI16XX_TTL_INIT 0
|
||||
#define APCI16XX_TTL_INITDIRECTION 1
|
||||
#define APCI16XX_TTL_OUTPUTMEMORY 2
|
||||
|
||||
#define APCI16XX_TTL_READCHANNEL 0
|
||||
#define APCI16XX_TTL_READPORT 1
|
||||
|
||||
#define APCI16XX_TTL_WRITECHANNEL_ON 0
|
||||
#define APCI16XX_TTL_WRITECHANNEL_OFF 1
|
||||
#define APCI16XX_TTL_WRITEPORT_ON 2
|
||||
#define APCI16XX_TTL_WRITEPORT_OFF 3
|
||||
|
||||
#define APCI16XX_TTL_READ_ALL_INPUTS 0
|
||||
#define APCI16XX_TTL_READ_ALL_OUTPUTS 1
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
static const struct comedi_lrange range_apci16xx_ttl = { 12,
|
||||
{BIP_RANGE(1),
|
||||
BIP_RANGE(1),
|
||||
BIP_RANGE(1),
|
||||
BIP_RANGE(1),
|
||||
BIP_RANGE(1),
|
||||
BIP_RANGE(1),
|
||||
BIP_RANGE(1),
|
||||
BIP_RANGE(1),
|
||||
BIP_RANGE(1),
|
||||
BIP_RANGE(1),
|
||||
BIP_RANGE(1),
|
||||
BIP_RANGE(1)}
|
||||
};
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| TTL INISIALISATION FUNCTION |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
int i_APCI16XX_InsnConfigInitTTLIO(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| TTL INPUT FUNCTION |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
int i_APCI16XX_InsnBitsReadTTLIO(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
|
||||
int i_APCI16XX_InsnReadTTLIOAllPortValue(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| TTL OUTPUT FUNCTIONS |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
int i_APCI16XX_InsnBitsWriteTTLIO(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
|
||||
int i_APCI16XX_Reset(struct comedi_device *dev);
|
||||
#endif
|
|
@ -0,0 +1,460 @@
|
|||
/**
|
||||
@verbatim
|
||||
|
||||
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
|
||||
ADDI-DATA GmbH
|
||||
Dieselstrasse 3
|
||||
D-77833 Ottersweier
|
||||
Tel: +19(0)7223/9493-0
|
||||
Fax: +49(0)7223/9493-92
|
||||
http://www.addi-data-com
|
||||
info@addi-data.com
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
You shoud also find the complete GPL in the COPYING file accompanying this source code.
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
/*
|
||||
|
||||
+-----------------------------------------------------------------------+
|
||||
| (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
|
||||
+-----------------------------------------------------------------------+
|
||||
| Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
|
||||
| Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
|
||||
+-------------------------------+---------------------------------------+
|
||||
| Project : APCI-2016 | Compiler : GCC |
|
||||
| Module name : hwdrv_apci2016.c| Version : 2.96 |
|
||||
+-------------------------------+---------------------------------------+
|
||||
| Project manager: Eric Stolz | Date : 02/12/2002 |
|
||||
+-------------------------------+---------------------------------------+
|
||||
| Description : Hardware Layer Acces For APCI-2016 |
|
||||
+-----------------------------------------------------------------------+
|
||||
| UPDATES |
|
||||
+----------+-----------+------------------------------------------------+
|
||||
| Date | Author | Description of updates |
|
||||
+----------+-----------+------------------------------------------------+
|
||||
| | | |
|
||||
| | | |
|
||||
| | | |
|
||||
+----------+-----------+------------------------------------------------+
|
||||
*/
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Included files |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
#include "hwdrv_apci2016.h"
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI2016_ConfigDigitalOutput |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s, |
|
||||
| struct comedi_insn *insn,unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Configures The Digital Output Subdevice. |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| UINT *data : Data Pointer contains |
|
||||
| configuration parameters as below |
|
||||
| |
|
||||
| data[0] : 1 Digital Memory On |
|
||||
| 0 Digital Memory Off |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
int i_APCI2016_ConfigDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
if ((data[0] != 0) && (data[0] != 1)) {
|
||||
comedi_error(dev,
|
||||
"Not a valid Data !!! ,Data should be 1 or 0\n");
|
||||
return -EINVAL;
|
||||
} // if ((data[0]!=0) && (data[0]!=1))
|
||||
if (data[0]) {
|
||||
devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
|
||||
} // if (data[0]
|
||||
else {
|
||||
devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
|
||||
} // else if (data[0]
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI2016_WriteDigitalOutput |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s, |
|
||||
| struct comedi_insn *insn,unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Writes port value To the selected port |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| UINT ui_NoOfChannels : No Of Channels To Write |
|
||||
| UINT *data : Data Pointer to read status |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
int i_APCI2016_WriteDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
UINT ui_NoOfChannel;
|
||||
UINT ui_Temp, ui_Temp1;
|
||||
ui_NoOfChannel = CR_CHAN(insn->chanspec);
|
||||
if ((ui_NoOfChannel < 0) || (ui_NoOfChannel > 15)) {
|
||||
comedi_error(dev,
|
||||
"Invalid Channel Numbers !!!, Channel Numbers must be between 0 and 15\n");
|
||||
return -EINVAL;
|
||||
} // if ((ui_NoOfChannel<0) || (ui_NoOfChannel>15))
|
||||
if (devpriv->b_OutputMemoryStatus) {
|
||||
ui_Temp = inw(devpriv->iobase + APCI2016_DIGITAL_OP);
|
||||
} // if (devpriv->b_OutputMemoryStatus )
|
||||
else {
|
||||
ui_Temp = 0;
|
||||
} // else if (devpriv->b_OutputMemoryStatus )
|
||||
if ((data[1] != 0) && (data[1] != 1)) {
|
||||
comedi_error(dev,
|
||||
"Invalid Data[1] value !!!, Data[1] should be 0 or 1\n");
|
||||
return -EINVAL;
|
||||
} // if ((data[1]!=0) && (data[1]!=1))
|
||||
|
||||
if (data[3] == 0) {
|
||||
if (data[1] == 0) {
|
||||
data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
|
||||
outw(data[0], devpriv->iobase + APCI2016_DIGITAL_OP);
|
||||
} // if (data[1]==0)
|
||||
else {
|
||||
if (data[1] == 1) {
|
||||
switch (ui_NoOfChannel) {
|
||||
case 2:
|
||||
data[0] =
|
||||
(data[0] << (2 *
|
||||
data[2])) | ui_Temp;
|
||||
break;
|
||||
case 4:
|
||||
data[0] =
|
||||
(data[0] << (4 *
|
||||
data[2])) | ui_Temp;
|
||||
break;
|
||||
case 8:
|
||||
data[0] =
|
||||
(data[0] << (8 *
|
||||
data[2])) | ui_Temp;
|
||||
break;
|
||||
case 15:
|
||||
data[0] = data[0] | ui_Temp;
|
||||
break;
|
||||
default:
|
||||
comedi_error(dev, " chan spec wrong");
|
||||
return -EINVAL; // "sorry channel spec wrong "
|
||||
} //switch(ui_NoOfChannels)
|
||||
outw(data[0],
|
||||
devpriv->iobase + APCI2016_DIGITAL_OP);
|
||||
} // if (data[1]==1)
|
||||
else {
|
||||
printk("\nSpecified channel not supported\n");
|
||||
} // else if (data[1]==1)
|
||||
} // else if (data[1]==0)
|
||||
} // if (data[3]==0)
|
||||
else {
|
||||
if (data[3] == 1) {
|
||||
if (data[1] == 0) {
|
||||
data[0] = ~data[0] & 0x1;
|
||||
ui_Temp1 = 1;
|
||||
ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
|
||||
ui_Temp = ui_Temp | ui_Temp1;
|
||||
data[0] = (data[0] << ui_NoOfChannel) ^ 0xffff;
|
||||
data[0] = data[0] & ui_Temp;
|
||||
outw(data[0],
|
||||
devpriv->iobase + APCI2016_DIGITAL_OP);
|
||||
} // if (data[1]==0)
|
||||
else {
|
||||
if (data[1] == 1) {
|
||||
switch (ui_NoOfChannel) {
|
||||
case 2:
|
||||
data[0] = ~data[0] & 0x3;
|
||||
ui_Temp1 = 3;
|
||||
ui_Temp1 =
|
||||
ui_Temp1 << 2 * data[2];
|
||||
ui_Temp = ui_Temp | ui_Temp1;
|
||||
data[0] =
|
||||
((data[0] << (2 *
|
||||
data
|
||||
[2])) ^
|
||||
0xffff) & ui_Temp;
|
||||
break;
|
||||
case 4:
|
||||
data[0] = ~data[0] & 0xf;
|
||||
ui_Temp1 = 15;
|
||||
ui_Temp1 =
|
||||
ui_Temp1 << 4 * data[2];
|
||||
ui_Temp = ui_Temp | ui_Temp1;
|
||||
data[0] =
|
||||
((data[0] << (4 *
|
||||
data
|
||||
[2])) ^
|
||||
0xffff) & ui_Temp;
|
||||
break;
|
||||
case 8:
|
||||
data[0] = ~data[0] & 0xff;
|
||||
ui_Temp1 = 255;
|
||||
ui_Temp1 =
|
||||
ui_Temp1 << 8 * data[2];
|
||||
ui_Temp = ui_Temp | ui_Temp1;
|
||||
data[0] =
|
||||
((data[0] << (8 *
|
||||
data
|
||||
[2])) ^
|
||||
0xffff) & ui_Temp;
|
||||
break;
|
||||
case 15:
|
||||
break;
|
||||
default:
|
||||
comedi_error(dev,
|
||||
" chan spec wrong");
|
||||
return -EINVAL; // "sorry channel spec wrong "
|
||||
} //switch(ui_NoOfChannels)
|
||||
outw(data[0],
|
||||
devpriv->iobase +
|
||||
APCI2016_DIGITAL_OP);
|
||||
} // if(data[1]==1)
|
||||
else {
|
||||
printk("\nSpecified channel not supported\n");
|
||||
} //else if(data[1]==1)
|
||||
} //elseif(data[1]==0)
|
||||
} //if(data[3]==1);
|
||||
else {
|
||||
printk("\nSpecified functionality does not exist\n");
|
||||
return -EINVAL;
|
||||
} //if else data[3]==1)
|
||||
} //if else data[3]==0)
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI2016_BitsDigitalOutput |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s, |
|
||||
| struct comedi_insn *insn,unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Read value of the selected channel or port |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| UINT ui_NoOfChannels : No Of Channels To read |
|
||||
| UINT *data : Data Pointer to read status |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
int i_APCI2016_BitsDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
UINT ui_Temp;
|
||||
UINT ui_NoOfChannel;
|
||||
ui_NoOfChannel = CR_CHAN(insn->chanspec);
|
||||
if ((ui_NoOfChannel < 0) || (ui_NoOfChannel > 15)) {
|
||||
comedi_error(dev,
|
||||
"Invalid Channel Numbers !!!, Channel Numbers must be between 0 and 15\n");
|
||||
return -EINVAL;
|
||||
} // if ((ui_NoOfChannel<0) || (ui_NoOfChannel>15))
|
||||
if ((data[0] != 0) && (data[0] != 1)) {
|
||||
comedi_error(dev,
|
||||
"Invalid Data[0] value !!!, Data[0] should be 0 or 1\n");
|
||||
return -EINVAL;
|
||||
} // if ((data[0]!=0) && (data[0]!=1))
|
||||
ui_Temp = data[0];
|
||||
*data = inw(devpriv->iobase + APCI2016_DIGITAL_OP_RW);
|
||||
if (ui_Temp == 0) {
|
||||
*data = (*data >> ui_NoOfChannel) & 0x1;
|
||||
} // if (ui_Temp==0)
|
||||
else {
|
||||
if (ui_Temp == 1) {
|
||||
switch (ui_NoOfChannel) {
|
||||
case 2:
|
||||
*data = (*data >> (2 * data[1])) & 3;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
*data = (*data >> (4 * data[1])) & 15;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
*data = (*data >> (8 * data[1])) & 255;
|
||||
break;
|
||||
|
||||
case 15:
|
||||
break;
|
||||
|
||||
default:
|
||||
comedi_error(dev, " chan spec wrong");
|
||||
return -EINVAL; // "sorry channel spec wrong "
|
||||
} //switch(ui_NoOfChannel)
|
||||
} // if (ui_Temp==1)
|
||||
else {
|
||||
printk("\nSpecified channel not supported \n");
|
||||
} // else if (ui_Temp==1)
|
||||
} // if (ui_Temp==0)
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI2016_ConfigWatchdog |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s, |
|
||||
| struct comedi_insn *insn,unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Configures The Watchdog |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| struct comedi_subdevice *s, :pointer to subdevice structure |
|
||||
| struct comedi_insn *insn :pointer to insn structure |
|
||||
| unsigned int *data : Data Pointer to read status |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
int i_APCI2016_ConfigWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
|
||||
if (data[0] == 0) {
|
||||
//Disable the watchdog
|
||||
outw(0x0,
|
||||
devpriv->i_IobaseAddon +
|
||||
APCI2016_WATCHDOG_ENABLEDISABLE);
|
||||
//Loading the Reload value
|
||||
outw(data[1],
|
||||
devpriv->i_IobaseAddon +
|
||||
APCI2016_WATCHDOG_RELOAD_VALUE);
|
||||
data[1] = data[1] >> 16;
|
||||
outw(data[1],
|
||||
devpriv->i_IobaseAddon +
|
||||
APCI2016_WATCHDOG_RELOAD_VALUE + 2);
|
||||
} else {
|
||||
printk("\nThe input parameters are wrong\n");
|
||||
}
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI2016_StartStopWriteWatchdog |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s, |
|
||||
| struct comedi_insn *insn,unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Start / Stop The Watchdog |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| struct comedi_subdevice *s, :pointer to subdevice structure |
|
||||
| struct comedi_insn *insn :pointer to insn structure |
|
||||
| unsigned int *data : Data Pointer to read status |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
int i_APCI2016_StartStopWriteWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
|
||||
switch (data[0]) {
|
||||
case 0: //stop the watchdog
|
||||
outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_ENABLEDISABLE); //disable the watchdog
|
||||
break;
|
||||
case 1: //start the watchdog
|
||||
outw(0x0001,
|
||||
devpriv->i_IobaseAddon +
|
||||
APCI2016_WATCHDOG_ENABLEDISABLE);
|
||||
break;
|
||||
case 2: //Software trigger
|
||||
outw(0x0201,
|
||||
devpriv->i_IobaseAddon +
|
||||
APCI2016_WATCHDOG_ENABLEDISABLE);
|
||||
break;
|
||||
default:
|
||||
printk("\nSpecified functionality does not exist\n");
|
||||
return -EINVAL;
|
||||
} // switch(data[0])
|
||||
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI2016_ReadWatchdog |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s, |
|
||||
| struct comedi_insn *insn,unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Read The Watchdog |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| struct comedi_subdevice *s, :pointer to subdevice structure |
|
||||
| struct comedi_insn *insn :pointer to insn structure |
|
||||
| unsigned int *data : Data Pointer to read status |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
int i_APCI2016_ReadWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
udelay(5);
|
||||
data[0] = inw(devpriv->i_IobaseAddon + APCI2016_WATCHDOG_STATUS) & 0x1;
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI2016_Reset(struct comedi_device *dev) | |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task :resets all the registers |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
INT i_APCI2016_Reset(struct comedi_device * dev)
|
||||
{
|
||||
outw(0x0, devpriv->iobase + APCI2016_DIGITAL_OP); // Resets the digital output channels
|
||||
outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_ENABLEDISABLE);
|
||||
outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_RELOAD_VALUE);
|
||||
outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_RELOAD_VALUE + 2);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
*
|
||||
* ADDI-DATA GmbH
|
||||
* Dieselstrasse 3
|
||||
* D-77833 Ottersweier
|
||||
* Tel: +19(0)7223/9493-0
|
||||
* Fax: +49(0)7223/9493-92
|
||||
* http://www.addi-data-com
|
||||
* info@addi-data.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*/
|
||||
/********* Definitions for APCI-2016 card *****/
|
||||
|
||||
#define APCI2016_BOARD_VENDOR_ID 0x15B8
|
||||
#define APCI2016_ADDRESS_RANGE 8
|
||||
|
||||
//DIGITAL INPUT-OUTPUT DEFINE
|
||||
|
||||
#define APCI2016_DIGITAL_OP 0x04
|
||||
#define APCI2016_DIGITAL_OP_RW 4
|
||||
|
||||
//ADDIDATA Enable Disable
|
||||
|
||||
#define ADDIDATA_ENABLE 1
|
||||
#define ADDIDATA_DISABLE 0
|
||||
|
||||
// TIMER COUNTER WATCHDOG DEFINES
|
||||
|
||||
#define ADDIDATA_WATCHDOG 2
|
||||
#define APCI2016_DIGITAL_OP_WATCHDOG 0
|
||||
#define APCI2016_WATCHDOG_ENABLEDISABLE 12
|
||||
#define APCI2016_WATCHDOG_RELOAD_VALUE 4
|
||||
#define APCI2016_WATCHDOG_STATUS 16
|
||||
|
||||
// Hardware Layer functions for Apci2016
|
||||
|
||||
//DO
|
||||
int i_APCI2016_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
int i_APCI2016_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
int i_APCI2016_BitsDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
// TIMER
|
||||
// timer value is passed as u seconds
|
||||
|
||||
int i_APCI2016_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
int i_APCI2016_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
int i_APCI2016_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
// Interrupt functions.....
|
||||
|
||||
// void v_APCI2016_Interrupt(int irq, void *d) ;
|
||||
|
||||
//void v_APCI2016_Interrupt(int irq, void *d);
|
||||
// RESET
|
||||
INT i_APCI2016_Reset(struct comedi_device *dev);
|
|
@ -0,0 +1,579 @@
|
|||
/**
|
||||
@verbatim
|
||||
|
||||
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
|
||||
ADDI-DATA GmbH
|
||||
Dieselstrasse 3
|
||||
D-77833 Ottersweier
|
||||
Tel: +19(0)7223/9493-0
|
||||
Fax: +49(0)7223/9493-92
|
||||
http://www.addi-data-com
|
||||
info@addi-data.com
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
You shoud also find the complete GPL in the COPYING file accompanying this source code.
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
/*
|
||||
|
||||
+-----------------------------------------------------------------------+
|
||||
| (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
|
||||
+-----------------------------------------------------------------------+
|
||||
| Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
|
||||
| Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
|
||||
+-------------------------------+---------------------------------------+
|
||||
| Project : APCI-2032 | Compiler : GCC |
|
||||
| Module name : hwdrv_apci2032.c| Version : 2.96 |
|
||||
+-------------------------------+---------------------------------------+
|
||||
| Project manager: Eric Stolz | Date : 02/12/2002 |
|
||||
+-------------------------------+---------------------------------------+
|
||||
| Description : Hardware Layer Acces For APCI-2032 |
|
||||
+-----------------------------------------------------------------------+
|
||||
| UPDATES |
|
||||
+----------+-----------+------------------------------------------------+
|
||||
| Date | Author | Description of updates |
|
||||
+----------+-----------+------------------------------------------------+
|
||||
| | | |
|
||||
| | | |
|
||||
| | | |
|
||||
+----------+-----------+------------------------------------------------+
|
||||
*/
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Included files |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include "hwdrv_apci2032.h"
|
||||
UINT ui_InterruptData, ui_Type;
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI2032_ConfigDigitalOutput |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s, |
|
||||
| struct comedi_insn *insn,unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Configures The Digital Output Subdevice. |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| UINT *data : Data Pointer contains |
|
||||
| configuration parameters as below |
|
||||
| |
|
||||
| data[1] : 1 Enable VCC Interrupt |
|
||||
| 0 Disable VCC Interrupt |
|
||||
| data[2] : 1 Enable CC Interrupt |
|
||||
| 0 Disable CC Interrupt |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
int i_APCI2032_ConfigDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
ULONG ul_Command = 0;
|
||||
devpriv->tsk_Current = current;
|
||||
|
||||
if ((data[0] != 0) && (data[0] != 1)) {
|
||||
comedi_error(dev,
|
||||
"Not a valid Data !!! ,Data should be 1 or 0\n");
|
||||
return -EINVAL;
|
||||
} //if ( (data[0]!=0) && (data[0]!=1) )
|
||||
if (data[0]) {
|
||||
devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
|
||||
} // if (data[0])
|
||||
else {
|
||||
devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
|
||||
} //else if (data[0])
|
||||
|
||||
if (data[1] == ADDIDATA_ENABLE) {
|
||||
ul_Command = ul_Command | 0x1;
|
||||
} //if (data[1] == ADDIDATA_ENABLE)
|
||||
else {
|
||||
ul_Command = ul_Command & 0xFFFFFFFE;
|
||||
} //elseif (data[1] == ADDIDATA_ENABLE)
|
||||
if (data[2] == ADDIDATA_ENABLE) {
|
||||
ul_Command = ul_Command | 0x2;
|
||||
} //if (data[2] == ADDIDATA_ENABLE)
|
||||
else {
|
||||
ul_Command = ul_Command & 0xFFFFFFFD;
|
||||
} //elseif (data[2] == ADDIDATA_ENABLE)
|
||||
outl(ul_Command, devpriv->iobase + APCI2032_DIGITAL_OP_INTERRUPT);
|
||||
ui_InterruptData = inl(devpriv->iobase + APCI2032_DIGITAL_OP_INTERRUPT);
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI2032_WriteDigitalOutput |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s, |
|
||||
| struct comedi_insn *insn,unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Writes port value To the selected port |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| UINT ui_NoOfChannels : No Of Channels To Write |
|
||||
| UINT *data : Data Pointer to read status |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
INT i_APCI2032_WriteDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
UINT ui_Temp, ui_Temp1;
|
||||
UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
|
||||
if (devpriv->b_OutputMemoryStatus) {
|
||||
ui_Temp = inl(devpriv->iobase + APCI2032_DIGITAL_OP);
|
||||
|
||||
} //if(devpriv->b_OutputMemoryStatus )
|
||||
else {
|
||||
ui_Temp = 0;
|
||||
} //if(devpriv->b_OutputMemoryStatus )
|
||||
if (data[3] == 0) {
|
||||
if (data[1] == 0) {
|
||||
data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
|
||||
outl(data[0], devpriv->iobase + APCI2032_DIGITAL_OP);
|
||||
} //if(data[1]==0)
|
||||
else {
|
||||
if (data[1] == 1) {
|
||||
switch (ui_NoOfChannel) {
|
||||
|
||||
case 2:
|
||||
data[0] =
|
||||
(data[0] << (2 *
|
||||
data[2])) | ui_Temp;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
data[0] =
|
||||
(data[0] << (4 *
|
||||
data[2])) | ui_Temp;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
data[0] =
|
||||
(data[0] << (8 *
|
||||
data[2])) | ui_Temp;
|
||||
break;
|
||||
|
||||
case 16:
|
||||
data[0] =
|
||||
(data[0] << (16 *
|
||||
data[2])) | ui_Temp;
|
||||
break;
|
||||
case 31:
|
||||
data[0] = data[0] | ui_Temp;
|
||||
break;
|
||||
|
||||
default:
|
||||
comedi_error(dev, " chan spec wrong");
|
||||
return -EINVAL; // "sorry channel spec wrong "
|
||||
|
||||
} //switch(ui_NoOfChannels)
|
||||
|
||||
outl(data[0],
|
||||
devpriv->iobase + APCI2032_DIGITAL_OP);
|
||||
} // if(data[1]==1)
|
||||
else {
|
||||
printk("\nSpecified channel not supported\n");
|
||||
} //else if(data[1]==1)
|
||||
} //elseif(data[1]==0)
|
||||
} //if(data[3]==0)
|
||||
else {
|
||||
if (data[3] == 1) {
|
||||
if (data[1] == 0) {
|
||||
data[0] = ~data[0] & 0x1;
|
||||
ui_Temp1 = 1;
|
||||
ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
|
||||
ui_Temp = ui_Temp | ui_Temp1;
|
||||
data[0] =
|
||||
(data[0] << ui_NoOfChannel) ^
|
||||
0xffffffff;
|
||||
data[0] = data[0] & ui_Temp;
|
||||
outl(data[0],
|
||||
devpriv->iobase + APCI2032_DIGITAL_OP);
|
||||
} //if(data[1]==0)
|
||||
else {
|
||||
if (data[1] == 1) {
|
||||
switch (ui_NoOfChannel) {
|
||||
|
||||
case 2:
|
||||
data[0] = ~data[0] & 0x3;
|
||||
ui_Temp1 = 3;
|
||||
ui_Temp1 =
|
||||
ui_Temp1 << 2 * data[2];
|
||||
ui_Temp = ui_Temp | ui_Temp1;
|
||||
data[0] =
|
||||
((data[0] << (2 *
|
||||
data
|
||||
[2])) ^
|
||||
0xffffffff) & ui_Temp;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
data[0] = ~data[0] & 0xf;
|
||||
ui_Temp1 = 15;
|
||||
ui_Temp1 =
|
||||
ui_Temp1 << 4 * data[2];
|
||||
ui_Temp = ui_Temp | ui_Temp1;
|
||||
data[0] =
|
||||
((data[0] << (4 *
|
||||
data
|
||||
[2])) ^
|
||||
0xffffffff) & ui_Temp;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
data[0] = ~data[0] & 0xff;
|
||||
ui_Temp1 = 255;
|
||||
ui_Temp1 =
|
||||
ui_Temp1 << 8 * data[2];
|
||||
ui_Temp = ui_Temp | ui_Temp1;
|
||||
data[0] =
|
||||
((data[0] << (8 *
|
||||
data
|
||||
[2])) ^
|
||||
0xffffffff) & ui_Temp;
|
||||
break;
|
||||
|
||||
case 16:
|
||||
data[0] = ~data[0] & 0xffff;
|
||||
ui_Temp1 = 65535;
|
||||
ui_Temp1 =
|
||||
ui_Temp1 << 16 *
|
||||
data[2];
|
||||
ui_Temp = ui_Temp | ui_Temp1;
|
||||
data[0] =
|
||||
((data[0] << (16 *
|
||||
data
|
||||
[2])) ^
|
||||
0xffffffff) & ui_Temp;
|
||||
break;
|
||||
|
||||
case 31:
|
||||
break;
|
||||
default:
|
||||
comedi_error(dev,
|
||||
" chan spec wrong");
|
||||
return -EINVAL; // "sorry channel spec wrong "
|
||||
|
||||
} //switch(ui_NoOfChannels)
|
||||
|
||||
outl(data[0],
|
||||
devpriv->iobase +
|
||||
APCI2032_DIGITAL_OP);
|
||||
} // if(data[1]==1)
|
||||
else {
|
||||
printk("\nSpecified channel not supported\n");
|
||||
} //else if(data[1]==1)
|
||||
} //elseif(data[1]==0)
|
||||
} //if(data[3]==1);
|
||||
else {
|
||||
printk("\nSpecified functionality does not exist\n");
|
||||
return -EINVAL;
|
||||
} //if else data[3]==1)
|
||||
} //if else data[3]==0)
|
||||
return (insn->n);;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI2032_ReadDigitalOutput |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s, |
|
||||
| struct comedi_insn *insn,unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Read value of the selected channel or port |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| UINT ui_NoOfChannels : No Of Channels To read |
|
||||
| UINT *data : Data Pointer to read status |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
INT i_APCI2032_ReadDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
UINT ui_Temp;
|
||||
UINT ui_NoOfChannel;
|
||||
ui_NoOfChannel = CR_CHAN(insn->chanspec);
|
||||
ui_Temp = data[0];
|
||||
*data = inl(devpriv->iobase + APCI2032_DIGITAL_OP_RW);
|
||||
if (ui_Temp == 0) {
|
||||
*data = (*data >> ui_NoOfChannel) & 0x1;
|
||||
} //if (ui_Temp==0)
|
||||
else {
|
||||
if (ui_Temp == 1) {
|
||||
switch (ui_NoOfChannel) {
|
||||
|
||||
case 2:
|
||||
*data = (*data >> (2 * data[1])) & 3;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
*data = (*data >> (4 * data[1])) & 15;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
*data = (*data >> (8 * data[1])) & 255;
|
||||
break;
|
||||
|
||||
case 16:
|
||||
*data = (*data >> (16 * data[1])) & 65535;
|
||||
break;
|
||||
|
||||
case 31:
|
||||
break;
|
||||
|
||||
default:
|
||||
comedi_error(dev, " chan spec wrong");
|
||||
return -EINVAL; // "sorry channel spec wrong "
|
||||
|
||||
} //switch(ui_NoOfChannels)
|
||||
} //if (ui_Temp==1)
|
||||
else {
|
||||
printk("\nSpecified channel not supported \n");
|
||||
} //elseif (ui_Temp==1)
|
||||
}
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : INT i_APCI2032_ConfigWatchdog(comedi_device
|
||||
*dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)|
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Configures The Watchdog |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| struct comedi_subdevice *s, :pointer to subdevice structure
|
||||
struct comedi_insn *insn :pointer to insn structure |
|
||||
| unsigned int *data : Data Pointer to read status |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
INT i_APCI2032_ConfigWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
if (data[0] == 0) {
|
||||
//Disable the watchdog
|
||||
outl(0x0,
|
||||
devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG +
|
||||
APCI2032_TCW_PROG);
|
||||
//Loading the Reload value
|
||||
outl(data[1],
|
||||
devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG +
|
||||
APCI2032_TCW_RELOAD_VALUE);
|
||||
} else {
|
||||
printk("\nThe input parameters are wrong\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI2032_StartStopWriteWatchdog |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,unsigned int *data); |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Start / Stop The Watchdog |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| struct comedi_subdevice *s, :pointer to subdevice structure
|
||||
struct comedi_insn *insn :pointer to insn structure |
|
||||
| unsigned int *data : Data Pointer to read status |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
int i_APCI2032_StartStopWriteWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
switch (data[0]) {
|
||||
case 0: //stop the watchdog
|
||||
outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + APCI2032_TCW_PROG); //disable the watchdog
|
||||
break;
|
||||
case 1: //start the watchdog
|
||||
outl(0x0001,
|
||||
devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG +
|
||||
APCI2032_TCW_PROG);
|
||||
break;
|
||||
case 2: //Software trigger
|
||||
outl(0x0201,
|
||||
devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG +
|
||||
APCI2032_TCW_PROG);
|
||||
break;
|
||||
default:
|
||||
printk("\nSpecified functionality does not exist\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI2032_ReadWatchdog |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
|
||||
unsigned int *data); |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Read The Watchdog |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| struct comedi_subdevice *s, :pointer to subdevice structure
|
||||
struct comedi_insn *insn :pointer to insn structure |
|
||||
| unsigned int *data : Data Pointer to read status |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
int i_APCI2032_ReadWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
|
||||
data[0] =
|
||||
inl(devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG +
|
||||
APCI2032_TCW_TRIG_STATUS) & 0x1;
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : void v_APCI2032_Interrupt |
|
||||
| (int irq , void *d) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Writes port value To the selected port |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : int irq : irq number |
|
||||
| void *d : void pointer |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
void v_APCI2032_Interrupt(int irq, void *d)
|
||||
{
|
||||
struct comedi_device *dev = d;
|
||||
unsigned int ui_DO;
|
||||
|
||||
ui_DO = inl(devpriv->iobase + APCI2032_DIGITAL_OP_IRQ) & 0x1; //Check if VCC OR CC interrupt has occured.
|
||||
|
||||
if (ui_DO == 0) {
|
||||
printk("\nInterrupt from unKnown source\n");
|
||||
} // if(ui_DO==0)
|
||||
if (ui_DO) {
|
||||
// Check for Digital Output interrupt Type - 1: Vcc interrupt 2: CC interrupt.
|
||||
ui_Type =
|
||||
inl(devpriv->iobase +
|
||||
APCI2032_DIGITAL_OP_INTERRUPT_STATUS) & 0x3;
|
||||
outl(0x0,
|
||||
devpriv->iobase + APCI2032_DIGITAL_OP +
|
||||
APCI2032_DIGITAL_OP_INTERRUPT);
|
||||
if (ui_Type == 1) {
|
||||
//Sends signal to user space
|
||||
send_sig(SIGIO, devpriv->tsk_Current, 0);
|
||||
} // if (ui_Type==1)
|
||||
else {
|
||||
if (ui_Type == 2) {
|
||||
// Sends signal to user space
|
||||
send_sig(SIGIO, devpriv->tsk_Current, 0);
|
||||
} //if (ui_Type==2)
|
||||
} //else if (ui_Type==1)
|
||||
} //if(ui_DO)
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI2032_ReadInterruptStatus |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s, |
|
||||
| struct comedi_insn *insn,unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task :Reads the interrupt status register |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
int i_APCI2032_ReadInterruptStatus(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
*data = ui_Type;
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI2032_Reset(struct comedi_device *dev) |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task :Resets the registers of the card |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
int i_APCI2032_Reset(struct comedi_device * dev)
|
||||
{
|
||||
devpriv->b_DigitalOutputRegister = 0;
|
||||
ui_Type = 0;
|
||||
outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP); //Resets the output channels
|
||||
outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_INTERRUPT); //Disables the interrupt.
|
||||
outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + APCI2032_TCW_PROG); //disable the watchdog
|
||||
outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + APCI2032_TCW_RELOAD_VALUE); //reload=0
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
*
|
||||
* ADDI-DATA GmbH
|
||||
* Dieselstrasse 3
|
||||
* D-77833 Ottersweier
|
||||
* Tel: +19(0)7223/9493-0
|
||||
* Fax: +49(0)7223/9493-92
|
||||
* http://www.addi-data-com
|
||||
* info@addi-data.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*/
|
||||
|
||||
/********* Definitions for APCI-2032 card *****/
|
||||
|
||||
// Card Specific information
|
||||
#define APCI2032_BOARD_VENDOR_ID 0x15B8
|
||||
#define APCI2032_ADDRESS_RANGE 63
|
||||
|
||||
//DIGITAL INPUT-OUTPUT DEFINE
|
||||
|
||||
#define APCI2032_DIGITAL_OP 0
|
||||
#define APCI2032_DIGITAL_OP_RW 0
|
||||
#define APCI2032_DIGITAL_OP_INTERRUPT 4
|
||||
#define APCI2032_DIGITAL_OP_IRQ 12
|
||||
|
||||
//Digital Output Interrupt Status
|
||||
#define APCI2032_DIGITAL_OP_INTERRUPT_STATUS 8
|
||||
|
||||
//Digital Output Interrupt Enable Disable.
|
||||
#define APCI2032_DIGITAL_OP_VCC_INTERRUPT_ENABLE 0x1
|
||||
#define APCI2032_DIGITAL_OP_VCC_INTERRUPT_DISABLE 0xFFFFFFFE
|
||||
#define APCI2032_DIGITAL_OP_CC_INTERRUPT_ENABLE 0x2
|
||||
#define APCI2032_DIGITAL_OP_CC_INTERRUPT_DISABLE 0xFFFFFFFD
|
||||
|
||||
//ADDIDATA Enable Disable
|
||||
|
||||
#define ADDIDATA_ENABLE 1
|
||||
#define ADDIDATA_DISABLE 0
|
||||
|
||||
// TIMER COUNTER WATCHDOG DEFINES
|
||||
|
||||
#define ADDIDATA_WATCHDOG 2
|
||||
#define APCI2032_DIGITAL_OP_WATCHDOG 16
|
||||
#define APCI2032_TCW_RELOAD_VALUE 4
|
||||
#define APCI2032_TCW_TIMEBASE 8
|
||||
#define APCI2032_TCW_PROG 12
|
||||
#define APCI2032_TCW_TRIG_STATUS 16
|
||||
#define APCI2032_TCW_IRQ 20
|
||||
|
||||
// Hardware Layer functions for Apci2032
|
||||
|
||||
//DO
|
||||
int i_APCI2032_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
INT i_APCI2032_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
INT i_APCI2032_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
int i_APCI2032_ReadInterruptStatus(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
// TIMER
|
||||
// timer value is passed as u seconds
|
||||
INT i_APCI2032_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
int i_APCI2032_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
int i_APCI2032_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
// Interrupt functions.....
|
||||
|
||||
void v_APCI2032_Interrupt(int irq, void *d);
|
||||
|
||||
//Reset functions
|
||||
int i_APCI2032_Reset(struct comedi_device *dev);
|
|
@ -0,0 +1,549 @@
|
|||
/**
|
||||
@verbatim
|
||||
|
||||
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
|
||||
ADDI-DATA GmbH
|
||||
Dieselstrasse 3
|
||||
D-77833 Ottersweier
|
||||
Tel: +19(0)7223/9493-0
|
||||
Fax: +49(0)7223/9493-92
|
||||
http://www.addi-data-com
|
||||
info@addi-data.com
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
You shoud also find the complete GPL in the COPYING file accompanying this source code.
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
/*
|
||||
|
||||
+-----------------------------------------------------------------------+
|
||||
| (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
|
||||
+-----------------------------------------------------------------------+
|
||||
| Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
|
||||
| Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
|
||||
+-------------------------------+---------------------------------------+
|
||||
| Project : APCI-2200 | Compiler : GCC |
|
||||
| Module name : hwdrv_apci2200.c| Version : 2.96 |
|
||||
+-------------------------------+---------------------------------------+
|
||||
| Project manager: Eric Stolz | Date : 02/12/2002 |
|
||||
+-------------------------------+---------------------------------------+
|
||||
| Description : Hardware Layer Acces For APCI-2200 |
|
||||
+-----------------------------------------------------------------------+
|
||||
| UPDATES |
|
||||
+----------+-----------+------------------------------------------------+
|
||||
| Date | Author | Description of updates |
|
||||
+----------+-----------+------------------------------------------------+
|
||||
| | | |
|
||||
| | | |
|
||||
| | | |
|
||||
+----------+-----------+------------------------------------------------+
|
||||
*/
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Included files |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
#include "hwdrv_apci2200.h"
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI2200_Read1DigitalInput |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s, |
|
||||
| struct comedi_insn *insn,unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Return the status of the digital input |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| struct comedi_subdevice *s, :pointer to subdevice structure
|
||||
struct comedi_insn *insn :pointer to insn structure |
|
||||
| unsigned int *data : Data Pointer to read status |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
INT i_APCI2200_Read1DigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
UINT ui_TmpValue = 0;
|
||||
UINT ui_Channel;
|
||||
ui_Channel = CR_CHAN(insn->chanspec);
|
||||
if (ui_Channel >= 0 && ui_Channel <= 7) {
|
||||
ui_TmpValue = (UINT) inw(devpriv->iobase + APCI2200_DIGITAL_IP);
|
||||
*data = (ui_TmpValue >> ui_Channel) & 0x1;
|
||||
} //if(ui_Channel >= 0 && ui_Channel <=7)
|
||||
else {
|
||||
printk("\nThe specified channel does not exist\n");
|
||||
return -EINVAL; // "sorry channel spec wrong "
|
||||
} //else if(ui_Channel >= 0 && ui_Channel <=7)
|
||||
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI2200_ReadMoreDigitalInput |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s, |
|
||||
| struct comedi_insn *insn,unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Return the status of the Requested digital inputs |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| struct comedi_subdevice *s, :pointer to subdevice structure
|
||||
struct comedi_insn *insn :pointer to insn structure |
|
||||
| unsigned int *data : Data Pointer to read status |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
INT i_APCI2200_ReadMoreDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
|
||||
UINT ui_PortValue = data[0];
|
||||
UINT ui_Mask = 0;
|
||||
UINT ui_NoOfChannels;
|
||||
|
||||
ui_NoOfChannels = CR_CHAN(insn->chanspec);
|
||||
|
||||
*data = (UINT) inw(devpriv->iobase + APCI2200_DIGITAL_IP);
|
||||
switch (ui_NoOfChannels) {
|
||||
case 2:
|
||||
ui_Mask = 3;
|
||||
*data = (*data >> (2 * ui_PortValue)) & ui_Mask;
|
||||
break;
|
||||
case 4:
|
||||
ui_Mask = 15;
|
||||
*data = (*data >> (4 * ui_PortValue)) & ui_Mask;
|
||||
break;
|
||||
case 7:
|
||||
break;
|
||||
|
||||
default:
|
||||
printk("\nWrong parameters\n");
|
||||
return -EINVAL; // "sorry channel spec wrong "
|
||||
break;
|
||||
} //switch(ui_NoOfChannels)
|
||||
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI2200_ConfigDigitalOutput (struct comedi_device *dev,
|
||||
struct comedi_subdevice *s struct comedi_insn *insn,unsigned int *data) |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Configures The Digital Output Subdevice. |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| unsigned int *data : Data Pointer contains |
|
||||
| configuration parameters as below |
|
||||
| struct comedi_subdevice *s, :pointer to subdevice structure
|
||||
struct comedi_insn *insn :pointer to insn structure |
|
||||
| data[0] :1:Memory on |
|
||||
| 0:Memory off |
|
||||
| |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
int i_APCI2200_ConfigDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
devpriv->b_OutputMemoryStatus = data[0];
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI2200_WriteDigitalOutput |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
|
||||
unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Writes port value To the selected port |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| struct comedi_subdevice *s, :pointer to subdevice structure
|
||||
struct comedi_insn *insn :pointer to insn structure |
|
||||
| unsigned int *data : Data Pointer to read status |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
INT i_APCI2200_WriteDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
UINT ui_Temp, ui_Temp1;
|
||||
UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
|
||||
if (devpriv->b_OutputMemoryStatus) {
|
||||
ui_Temp = inw(devpriv->iobase + APCI2200_DIGITAL_OP);
|
||||
|
||||
} //if(devpriv->b_OutputMemoryStatus )
|
||||
else {
|
||||
ui_Temp = 0;
|
||||
} //if(devpriv->b_OutputMemoryStatus )
|
||||
if (data[3] == 0) {
|
||||
if (data[1] == 0) {
|
||||
data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
|
||||
outw(data[0], devpriv->iobase + APCI2200_DIGITAL_OP);
|
||||
} //if(data[1]==0)
|
||||
else {
|
||||
if (data[1] == 1) {
|
||||
switch (ui_NoOfChannel) {
|
||||
|
||||
case 2:
|
||||
data[0] =
|
||||
(data[0] << (2 *
|
||||
data[2])) | ui_Temp;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
data[0] =
|
||||
(data[0] << (4 *
|
||||
data[2])) | ui_Temp;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
data[0] =
|
||||
(data[0] << (8 *
|
||||
data[2])) | ui_Temp;
|
||||
break;
|
||||
case 15:
|
||||
data[0] = data[0] | ui_Temp;
|
||||
break;
|
||||
default:
|
||||
comedi_error(dev, " chan spec wrong");
|
||||
return -EINVAL; // "sorry channel spec wrong "
|
||||
|
||||
} //switch(ui_NoOfChannels)
|
||||
|
||||
outw(data[0],
|
||||
devpriv->iobase + APCI2200_DIGITAL_OP);
|
||||
} // if(data[1]==1)
|
||||
else {
|
||||
printk("\nSpecified channel not supported\n");
|
||||
} //else if(data[1]==1)
|
||||
} //elseif(data[1]==0)
|
||||
} //if(data[3]==0)
|
||||
else {
|
||||
if (data[3] == 1) {
|
||||
if (data[1] == 0) {
|
||||
data[0] = ~data[0] & 0x1;
|
||||
ui_Temp1 = 1;
|
||||
ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
|
||||
ui_Temp = ui_Temp | ui_Temp1;
|
||||
data[0] = (data[0] << ui_NoOfChannel) ^ 0xffff;
|
||||
data[0] = data[0] & ui_Temp;
|
||||
outw(data[0],
|
||||
devpriv->iobase + APCI2200_DIGITAL_OP);
|
||||
} //if(data[1]==0)
|
||||
else {
|
||||
if (data[1] == 1) {
|
||||
switch (ui_NoOfChannel) {
|
||||
|
||||
case 2:
|
||||
data[0] = ~data[0] & 0x3;
|
||||
ui_Temp1 = 3;
|
||||
ui_Temp1 =
|
||||
ui_Temp1 << 2 * data[2];
|
||||
ui_Temp = ui_Temp | ui_Temp1;
|
||||
data[0] =
|
||||
((data[0] << (2 *
|
||||
data
|
||||
[2])) ^
|
||||
0xffff) & ui_Temp;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
data[0] = ~data[0] & 0xf;
|
||||
ui_Temp1 = 15;
|
||||
ui_Temp1 =
|
||||
ui_Temp1 << 4 * data[2];
|
||||
ui_Temp = ui_Temp | ui_Temp1;
|
||||
data[0] =
|
||||
((data[0] << (4 *
|
||||
data
|
||||
[2])) ^
|
||||
0xffff) & ui_Temp;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
data[0] = ~data[0] & 0xff;
|
||||
ui_Temp1 = 255;
|
||||
ui_Temp1 =
|
||||
ui_Temp1 << 8 * data[2];
|
||||
ui_Temp = ui_Temp | ui_Temp1;
|
||||
data[0] =
|
||||
((data[0] << (8 *
|
||||
data
|
||||
[2])) ^
|
||||
0xffff) & ui_Temp;
|
||||
break;
|
||||
case 15:
|
||||
break;
|
||||
|
||||
default:
|
||||
comedi_error(dev,
|
||||
" chan spec wrong");
|
||||
return -EINVAL; // "sorry channel spec wrong "
|
||||
|
||||
} //switch(ui_NoOfChannels)
|
||||
|
||||
outw(data[0],
|
||||
devpriv->iobase +
|
||||
APCI2200_DIGITAL_OP);
|
||||
} // if(data[1]==1)
|
||||
else {
|
||||
printk("\nSpecified channel not supported\n");
|
||||
} //else if(data[1]==1)
|
||||
} //elseif(data[1]==0)
|
||||
} //if(data[3]==1);
|
||||
else {
|
||||
printk("\nSpecified functionality does not exist\n");
|
||||
return -EINVAL;
|
||||
} //if else data[3]==1)
|
||||
} //if else data[3]==0)
|
||||
return (insn->n);;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI2200_ReadDigitalOutput |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
|
||||
unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Read value of the selected channel or port |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| struct comedi_subdevice *s, :pointer to subdevice structure
|
||||
struct comedi_insn *insn :pointer to insn structure |
|
||||
| unsigned int *data : Data Pointer to read status |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
INT i_APCI2200_ReadDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
|
||||
UINT ui_Temp;
|
||||
UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
|
||||
ui_Temp = data[0];
|
||||
*data = inw(devpriv->iobase + APCI2200_DIGITAL_OP);
|
||||
if (ui_Temp == 0) {
|
||||
*data = (*data >> ui_NoOfChannel) & 0x1;
|
||||
} //if(ui_Temp==0)
|
||||
else {
|
||||
if (ui_Temp == 1) {
|
||||
switch (ui_NoOfChannel) {
|
||||
|
||||
case 2:
|
||||
*data = (*data >> (2 * data[1])) & 3;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
*data = (*data >> (4 * data[1])) & 15;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
*data = (*data >> (8 * data[1])) & 255;
|
||||
break;
|
||||
|
||||
case 15:
|
||||
break;
|
||||
|
||||
default:
|
||||
comedi_error(dev, " chan spec wrong");
|
||||
return -EINVAL; // "sorry channel spec wrong "
|
||||
|
||||
} //switch(ui_NoOfChannels)
|
||||
} //if(ui_Temp==1)
|
||||
else {
|
||||
printk("\nSpecified channel not supported \n");
|
||||
} //elseif(ui_Temp==1)
|
||||
} //elseif(ui_Temp==0)
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI2200_ConfigWatchdog(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Configures The Watchdog |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| struct comedi_subdevice *s, :pointer to subdevice structure
|
||||
struct comedi_insn *insn :pointer to insn structure |
|
||||
| unsigned int *data : Data Pointer to read status |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
int i_APCI2200_ConfigWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
if (data[0] == 0) {
|
||||
//Disable the watchdog
|
||||
outw(0x0,
|
||||
devpriv->iobase + APCI2200_WATCHDOG +
|
||||
APCI2200_WATCHDOG_ENABLEDISABLE);
|
||||
//Loading the Reload value
|
||||
outw(data[1],
|
||||
devpriv->iobase + APCI2200_WATCHDOG +
|
||||
APCI2200_WATCHDOG_RELOAD_VALUE);
|
||||
data[1] = data[1] >> 16;
|
||||
outw(data[1],
|
||||
devpriv->iobase + APCI2200_WATCHDOG +
|
||||
APCI2200_WATCHDOG_RELOAD_VALUE + 2);
|
||||
} //if(data[0]==0)
|
||||
else {
|
||||
printk("\nThe input parameters are wrong\n");
|
||||
return -EINVAL;
|
||||
} //elseif(data[0]==0)
|
||||
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI2200_StartStopWriteWatchdog |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,unsigned int *data); |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Start / Stop The Watchdog |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| struct comedi_subdevice *s, :pointer to subdevice structure
|
||||
struct comedi_insn *insn :pointer to insn structure |
|
||||
| unsigned int *data : Data Pointer to read status |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
int i_APCI2200_StartStopWriteWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
switch (data[0]) {
|
||||
case 0: //stop the watchdog
|
||||
outw(0x0, devpriv->iobase + APCI2200_WATCHDOG + APCI2200_WATCHDOG_ENABLEDISABLE); //disable the watchdog
|
||||
break;
|
||||
case 1: //start the watchdog
|
||||
outw(0x0001,
|
||||
devpriv->iobase + APCI2200_WATCHDOG +
|
||||
APCI2200_WATCHDOG_ENABLEDISABLE);
|
||||
break;
|
||||
case 2: //Software trigger
|
||||
outw(0x0201,
|
||||
devpriv->iobase + APCI2200_WATCHDOG +
|
||||
APCI2200_WATCHDOG_ENABLEDISABLE);
|
||||
break;
|
||||
default:
|
||||
printk("\nSpecified functionality does not exist\n");
|
||||
return -EINVAL;
|
||||
} // switch(data[0])
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI2200_ReadWatchdog |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
|
||||
unsigned int *data); |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Read The Watchdog |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| struct comedi_subdevice *s, :pointer to subdevice structure
|
||||
struct comedi_insn *insn :pointer to insn structure |
|
||||
| unsigned int *data : Data Pointer to read status |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
int i_APCI2200_ReadWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
data[0] =
|
||||
inw(devpriv->iobase + APCI2200_WATCHDOG +
|
||||
APCI2200_WATCHDOG_STATUS) & 0x1;
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI2200_Reset(struct comedi_device *dev) | |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task :resets all the registers |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
INT i_APCI2200_Reset(struct comedi_device * dev)
|
||||
{
|
||||
outw(0x0, devpriv->iobase + APCI2200_DIGITAL_OP); //RESETS THE DIGITAL OUTPUTS
|
||||
outw(0x0,
|
||||
devpriv->iobase + APCI2200_WATCHDOG +
|
||||
APCI2200_WATCHDOG_ENABLEDISABLE);
|
||||
outw(0x0,
|
||||
devpriv->iobase + APCI2200_WATCHDOG +
|
||||
APCI2200_WATCHDOG_RELOAD_VALUE);
|
||||
outw(0x0,
|
||||
devpriv->iobase + APCI2200_WATCHDOG +
|
||||
APCI2200_WATCHDOG_RELOAD_VALUE + 2);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
*
|
||||
* ADDI-DATA GmbH
|
||||
* Dieselstrasse 3
|
||||
* D-77833 Ottersweier
|
||||
* Tel: +19(0)7223/9493-0
|
||||
* Fax: +49(0)7223/9493-92
|
||||
* http://www.addi-data-com
|
||||
* info@addi-data.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*/
|
||||
|
||||
/********* Definitions for APCI-2200 card *****/
|
||||
|
||||
// Card Specific information
|
||||
#define APCI2200_BOARD_VENDOR_ID 0x15b8
|
||||
#define APCI2200_ADDRESS_RANGE 64
|
||||
|
||||
//DIGITAL INPUT-OUTPUT DEFINE
|
||||
|
||||
#define APCI2200_DIGITAL_OP 4
|
||||
#define APCI2200_DIGITAL_IP 0
|
||||
|
||||
// TIMER COUNTER WATCHDOG DEFINES
|
||||
|
||||
#define APCI2200_WATCHDOG 0x08
|
||||
#define APCI2200_WATCHDOG_ENABLEDISABLE 12
|
||||
#define APCI2200_WATCHDOG_RELOAD_VALUE 4
|
||||
#define APCI2200_WATCHDOG_STATUS 16
|
||||
|
||||
// Hardware Layer functions for Apci2200
|
||||
|
||||
//Digital Input
|
||||
INT i_APCI2200_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
INT i_APCI2200_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
//Digital Output
|
||||
int i_APCI2200_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
INT i_APCI2200_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
INT i_APCI2200_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
// TIMER
|
||||
int i_APCI2200_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
int i_APCI2200_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
int i_APCI2200_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
//reset
|
||||
INT i_APCI2200_Reset(struct comedi_device *dev);
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,241 @@
|
|||
|
||||
// hwdrv_apci3120.h
|
||||
|
||||
/*
|
||||
* Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
*
|
||||
* ADDI-DATA GmbH
|
||||
* Dieselstrasse 3
|
||||
* D-77833 Ottersweier
|
||||
* Tel: +19(0)7223/9493-0
|
||||
* Fax: +49(0)7223/9493-92
|
||||
* http://www.addi-data-com
|
||||
* info@addi-data.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*/
|
||||
|
||||
// comedi related defines
|
||||
|
||||
//ANALOG INPUT RANGE
|
||||
static const struct comedi_lrange range_apci3120_ai = { 8, {
|
||||
BIP_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(2),
|
||||
BIP_RANGE(1),
|
||||
UNI_RANGE(10),
|
||||
UNI_RANGE(5),
|
||||
UNI_RANGE(2),
|
||||
UNI_RANGE(1)
|
||||
}
|
||||
};
|
||||
|
||||
// ANALOG OUTPUT RANGE
|
||||
static const struct comedi_lrange range_apci3120_ao = { 2, {
|
||||
BIP_RANGE(10),
|
||||
UNI_RANGE(10)
|
||||
}
|
||||
};
|
||||
|
||||
#define APCI3120_BIPOLAR_RANGES 4 // used for test on mixture of BIP/UNI ranges
|
||||
|
||||
#define APCI3120_BOARD_VENDOR_ID 0x10E8
|
||||
#define APCI3120_ADDRESS_RANGE 16
|
||||
|
||||
#define APCI3120_DISABLE 0
|
||||
#define APCI3120_ENABLE 1
|
||||
|
||||
#define APCI3120_START 1
|
||||
#define APCI3120_STOP 0
|
||||
|
||||
#define APCI3120_EOC_MODE 1
|
||||
#define APCI3120_EOS_MODE 2
|
||||
#define APCI3120_DMA_MODE 3
|
||||
|
||||
//DIGITAL INPUT-OUTPUT DEFINE
|
||||
|
||||
#define APCI3120_DIGITAL_OUTPUT 0x0D
|
||||
#define APCI3120_RD_STATUS 0x02
|
||||
#define APCI3120_RD_FIFO 0x00
|
||||
|
||||
// digital output insn_write ON /OFF selection
|
||||
#define APCI3120_SET4DIGITALOUTPUTON 1
|
||||
#define APCI3120_SET4DIGITALOUTPUTOFF 0
|
||||
|
||||
// analog output SELECT BIT
|
||||
#define APCI3120_ANALOG_OP_CHANNEL_1 0x0000
|
||||
#define APCI3120_ANALOG_OP_CHANNEL_2 0x4000
|
||||
#define APCI3120_ANALOG_OP_CHANNEL_3 0x8000
|
||||
#define APCI3120_ANALOG_OP_CHANNEL_4 0xC000
|
||||
#define APCI3120_ANALOG_OP_CHANNEL_5 0x0000
|
||||
#define APCI3120_ANALOG_OP_CHANNEL_6 0x4000
|
||||
#define APCI3120_ANALOG_OP_CHANNEL_7 0x8000
|
||||
#define APCI3120_ANALOG_OP_CHANNEL_8 0xC000
|
||||
|
||||
// Enable external trigger bit in nWrAddress
|
||||
#define APCI3120_ENABLE_EXT_TRIGGER 0x8000
|
||||
|
||||
//ANALOG OUTPUT AND INPUT DEFINE
|
||||
#define APCI3120_UNIPOLAR 0x80 //$$ RAM sequence polarity BIT
|
||||
#define APCI3120_BIPOLAR 0x00 //$$ RAM sequence polarity BIT
|
||||
#define APCI3120_ANALOG_OUTPUT_1 0x08 // (ADDRESS )
|
||||
#define APCI3120_ANALOG_OUTPUT_2 0x0A // (ADDRESS )
|
||||
#define APCI3120_1_GAIN 0x00 //$$ RAM sequence Gain Bits for gain 1
|
||||
#define APCI3120_2_GAIN 0x10 //$$ RAM sequence Gain Bits for gain 2
|
||||
#define APCI3120_5_GAIN 0x20 //$$ RAM sequence Gain Bits for gain 5
|
||||
#define APCI3120_10_GAIN 0x30 //$$ RAM sequence Gain Bits for gain 10
|
||||
#define APCI3120_SEQ_RAM_ADDRESS 0x06 //$$ EARLIER NAMED APCI3120_FIFO_ADDRESS
|
||||
#define APCI3120_RESET_FIFO 0x0C //(ADDRESS)
|
||||
#define APCI3120_TIMER_0_MODE_2 0x01 //$$ Bits for timer mode
|
||||
#define APCI3120_TIMER_0_MODE_4 0x2
|
||||
#define APCI3120_SELECT_TIMER_0_WORD 0x00
|
||||
#define APCI3120_ENABLE_TIMER0 0x1000 //$$Gatebit 0 in nWrAddress
|
||||
#define APCI3120_CLEAR_PR 0xF0FF
|
||||
#define APCI3120_CLEAR_PA 0xFFF0
|
||||
#define APCI3120_CLEAR_PA_PR (APCI3120_CLEAR_PR & APCI3120_CLEAR_PA)
|
||||
|
||||
// nWrMode_Select
|
||||
#define APCI3120_ENABLE_SCAN 0x8 //$$ bit in nWrMode_Select
|
||||
#define APCI3120_DISABLE_SCAN (~APCI3120_ENABLE_SCAN)
|
||||
#define APCI3120_ENABLE_EOS_INT 0x2 //$$ bit in nWrMode_Select
|
||||
|
||||
#define APCI3120_DISABLE_EOS_INT (~APCI3120_ENABLE_EOS_INT)
|
||||
#define APCI3120_ENABLE_EOC_INT 0x1
|
||||
#define APCI3120_DISABLE_EOC_INT (~APCI3120_ENABLE_EOC_INT)
|
||||
#define APCI3120_DISABLE_ALL_INTERRUPT_WITHOUT_TIMER (APCI3120_DISABLE_EOS_INT & APCI3120_DISABLE_EOC_INT)
|
||||
#define APCI3120_DISABLE_ALL_INTERRUPT (APCI3120_DISABLE_TIMER_INT & APCI3120_DISABLE_EOS_INT & APCI3120_DISABLE_EOC_INT)
|
||||
|
||||
//status register bits
|
||||
#define APCI3120_EOC 0x8000
|
||||
#define APCI3120_EOS 0x2000
|
||||
|
||||
// software trigger dummy register
|
||||
#define APCI3120_START_CONVERSION 0x02 //(ADDRESS)
|
||||
|
||||
//TIMER DEFINE
|
||||
#define APCI3120_QUARTZ_A 70
|
||||
#define APCI3120_QUARTZ_B 50
|
||||
#define APCI3120_TIMER 1
|
||||
#define APCI3120_WATCHDOG 2
|
||||
#define APCI3120_TIMER_DISABLE 0
|
||||
#define APCI3120_TIMER_ENABLE 1
|
||||
#define APCI3120_ENABLE_TIMER2 0x4000 //$$ gatebit 2 in nWrAddress
|
||||
#define APCI3120_DISABLE_TIMER2 (~APCI3120_ENABLE_TIMER2)
|
||||
#define APCI3120_ENABLE_TIMER_INT 0x04 //$$ ENAIRQ_FC_Bit in nWrModeSelect
|
||||
#define APCI3120_DISABLE_TIMER_INT (~APCI3120_ENABLE_TIMER_INT)
|
||||
#define APCI3120_WRITE_MODE_SELECT 0x0E // (ADDRESS)
|
||||
#define APCI3120_SELECT_TIMER_0_WORD 0x00
|
||||
#define APCI3120_SELECT_TIMER_1_WORD 0x01
|
||||
#define APCI3120_TIMER_1_MODE_2 0x4
|
||||
|
||||
//$$ BIT FOR MODE IN nCsTimerCtr1
|
||||
#define APCI3120_TIMER_2_MODE_0 0x0
|
||||
#define APCI3120_TIMER_2_MODE_2 0x10
|
||||
#define APCI3120_TIMER_2_MODE_5 0x30
|
||||
|
||||
//$$ BIT FOR MODE IN nCsTimerCtr0
|
||||
#define APCI3120_SELECT_TIMER_2_LOW_WORD 0x02
|
||||
#define APCI3120_SELECT_TIMER_2_HIGH_WORD 0x03
|
||||
|
||||
#define APCI3120_TIMER_CRT0 0x0D //(ADDRESS for cCsTimerCtr0)
|
||||
#define APCI3120_TIMER_CRT1 0x0C //(ADDRESS for cCsTimerCtr1)
|
||||
|
||||
#define APCI3120_TIMER_VALUE 0x04 //ADDRESS for nCsTimerWert
|
||||
#define APCI3120_TIMER_STATUS_REGISTER 0x0D //ADDRESS for delete timer 2 interrupt
|
||||
#define APCI3120_RD_STATUS 0x02 //ADDRESS
|
||||
#define APCI3120_WR_ADDRESS 0x00 //ADDRESS
|
||||
#define APCI3120_ENABLE_WATCHDOG 0x20 //$$BIT in nWrMode_Select
|
||||
#define APCI3120_DISABLE_WATCHDOG (~APCI3120_ENABLE_WATCHDOG)
|
||||
#define APCI3120_ENABLE_TIMER_COUNTER 0x10 //$$BIT in nWrMode_Select
|
||||
#define APCI3120_DISABLE_TIMER_COUNTER (~APCI3120_ENABLE_TIMER_COUNTER)
|
||||
#define APCI3120_FC_TIMER 0x1000 //bit in status register
|
||||
#define APCI3120_ENABLE_TIMER0 0x1000
|
||||
#define APCI3120_ENABLE_TIMER1 0x2000
|
||||
#define APCI3120_ENABLE_TIMER2 0x4000
|
||||
#define APCI3120_DISABLE_TIMER0 (~APCI3120_ENABLE_TIMER0)
|
||||
#define APCI3120_DISABLE_TIMER1 (~APCI3120_ENABLE_TIMER1)
|
||||
#define APCI3120_DISABLE_TIMER2 (~APCI3120_ENABLE_TIMER2)
|
||||
|
||||
#define APCI3120_TIMER2_SELECT_EOS 0xC0 // ADDED on 20-6
|
||||
#define APCI3120_COUNTER 3 // on 20-6
|
||||
#define APCI3120_DISABLE_ALL_TIMER ( APCI3120_DISABLE_TIMER0 & APCI3120_DISABLE_TIMER1 & APCI3120_DISABLE_TIMER2 ) // on 20-6
|
||||
|
||||
#define MAX_ANALOGINPUT_CHANNELS 32
|
||||
|
||||
typedef struct {
|
||||
BYTE b_Type; /* EOC or EOS */
|
||||
BYTE b_InterruptFlag; /* Interrupt use or not */
|
||||
UINT ui_ConvertTiming; /* Selection of the convertion time */
|
||||
BYTE b_NbrOfChannel; /* Number of channel to read */
|
||||
UINT ui_ChannelList[MAX_ANALOGINPUT_CHANNELS]; /* Number of the channel to be read */
|
||||
UINT ui_RangeList[MAX_ANALOGINPUT_CHANNELS]; /* Gain of each channel */
|
||||
|
||||
} str_AnalogReadInformation;
|
||||
|
||||
// Function Declaration For APCI-3120
|
||||
|
||||
// Internal functions
|
||||
int i_APCI3120_SetupChannelList(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
int n_chan, unsigned int *chanlist, char check);
|
||||
int i_APCI3120_ExttrigEnable(struct comedi_device *dev);
|
||||
int i_APCI3120_ExttrigDisable(struct comedi_device *dev);
|
||||
int i_APCI3120_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_subdevice *s);
|
||||
int i_APCI3120_Reset(struct comedi_device *dev);
|
||||
int i_APCI3120_CyclicAnalogInput(int mode, struct comedi_device *dev,
|
||||
struct comedi_subdevice *s);
|
||||
// Interrupt functions
|
||||
void v_APCI3120_Interrupt(int irq, void *d);
|
||||
//UPDATE-0.7.57->0.7.68 void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device *dev,struct comedi_subdevice *s,short *dma,short *data,int n);
|
||||
void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
short *dma_buffer,
|
||||
unsigned int num_samples);
|
||||
int i_APCI3120_InterruptHandleEos(struct comedi_device *dev);
|
||||
void v_APCI3120_InterruptDma(int irq, void *d);
|
||||
|
||||
// TIMER
|
||||
|
||||
int i_APCI3120_InsnConfigTimer(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
int i_APCI3120_InsnReadTimer(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
//DI
|
||||
// for di read
|
||||
|
||||
int i_APCI3120_InsnBitsDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
int i_APCI3120_InsnReadDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
//DO
|
||||
//int i_APCI3120_WriteDigitalOutput(struct comedi_device *dev, BYTE data);
|
||||
int i_APCI3120_InsnConfigDigitalOutput(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
int i_APCI3120_InsnBitsDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
//AO
|
||||
//int i_APCI3120_Write1AnalogValue(struct comedi_device *dev,UINT ui_Range,UINT ui_Channel,UINT data );
|
||||
int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
//AI HArdware layer
|
||||
|
||||
int i_APCI3120_InsnConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
int i_APCI3120_InsnReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd);
|
||||
int i_APCI3120_CommandAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s);
|
||||
//int i_APCI3120_CancelAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s);
|
||||
int i_APCI3120_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_subdevice *s);
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
* Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
*
|
||||
* ADDI-DATA GmbH
|
||||
* Dieselstrasse 3
|
||||
* D-77833 Ottersweier
|
||||
* Tel: +19(0)7223/9493-0
|
||||
* Fax: +49(0)7223/9493-92
|
||||
* http://www.addi-data-com
|
||||
* info@addi-data.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*/
|
||||
|
||||
// Card Specific information
|
||||
#define APCI3200_BOARD_VENDOR_ID 0x15B8
|
||||
//#define APCI3200_ADDRESS_RANGE 264
|
||||
|
||||
int MODULE_NO;
|
||||
struct {
|
||||
INT i_Gain;
|
||||
INT i_Polarity;
|
||||
INT i_OffsetRange;
|
||||
INT i_Coupling;
|
||||
INT i_SingleDiff;
|
||||
INT i_AutoCalibration;
|
||||
UINT ui_ReloadValue;
|
||||
UINT ui_TimeUnitReloadVal;
|
||||
INT i_Interrupt;
|
||||
INT i_ModuleSelection;
|
||||
} Config_Parameters_Module1, Config_Parameters_Module2,
|
||||
Config_Parameters_Module3, Config_Parameters_Module4;
|
||||
|
||||
//ANALOG INPUT RANGE
|
||||
static const struct comedi_lrange range_apci3200_ai = { 8, {
|
||||
BIP_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(2),
|
||||
BIP_RANGE(1),
|
||||
UNI_RANGE(10),
|
||||
UNI_RANGE(5),
|
||||
UNI_RANGE(2),
|
||||
UNI_RANGE(1)
|
||||
}
|
||||
};
|
||||
|
||||
static const struct comedi_lrange range_apci3300_ai = { 4, {
|
||||
UNI_RANGE(10),
|
||||
UNI_RANGE(5),
|
||||
UNI_RANGE(2),
|
||||
UNI_RANGE(1)
|
||||
}
|
||||
};
|
||||
|
||||
//Analog Input related Defines
|
||||
#define APCI3200_AI_OFFSET_GAIN 0
|
||||
#define APCI3200_AI_SC_TEST 4
|
||||
#define APCI3200_AI_IRQ 8
|
||||
#define APCI3200_AI_AUTOCAL 12
|
||||
#define APCI3200_RELOAD_CONV_TIME_VAL 32
|
||||
#define APCI3200_CONV_TIME_TIME_BASE 36
|
||||
#define APCI3200_RELOAD_DELAY_TIME_VAL 40
|
||||
#define APCI3200_DELAY_TIME_TIME_BASE 44
|
||||
#define APCI3200_AI_MODULE1 0
|
||||
#define APCI3200_AI_MODULE2 64
|
||||
#define APCI3200_AI_MODULE3 128
|
||||
#define APCI3200_AI_MODULE4 192
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define APCI3200_AI_EOSIRQ 16
|
||||
#define APCI3200_AI_EOS 20
|
||||
#define APCI3200_AI_CHAN_ID 24
|
||||
#define APCI3200_AI_CHAN_VAL 28
|
||||
#define ANALOG_INPUT 0
|
||||
#define TEMPERATURE 1
|
||||
#define RESISTANCE 2
|
||||
|
||||
#define ENABLE_EXT_TRIG 1
|
||||
#define ENABLE_EXT_GATE 2
|
||||
#define ENABLE_EXT_TRIG_GATE 3
|
||||
|
||||
#define APCI3200_MAXVOLT 2.5
|
||||
#define ADDIDATA_GREATER_THAN_TEST 0
|
||||
#define ADDIDATA_LESS_THAN_TEST 1
|
||||
|
||||
#define ADDIDATA_UNIPOLAR 1
|
||||
#define ADDIDATA_BIPOLAR 2
|
||||
|
||||
//BEGIN JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
|
||||
#define MAX_MODULE 4
|
||||
//END JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
|
||||
|
||||
typedef struct {
|
||||
ULONG ul_NumberOfValue;
|
||||
ULONG *pul_ResistanceValue;
|
||||
ULONG *pul_TemperatureValue;
|
||||
} str_ADDIDATA_RTDStruct, *pstr_ADDIDATA_RTDStruct;
|
||||
|
||||
//BEGIN JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
|
||||
typedef struct {
|
||||
// Begin JK 05/08/2003 change for Linux
|
||||
unsigned long ul_CurrentSourceCJC;
|
||||
unsigned long ul_CurrentSource[5];
|
||||
// End JK 05/08/2003 change for Linux
|
||||
|
||||
// Begin CG 15/02/02 Rev 1.0 -> Rev 1.1 : Add Header Type 1
|
||||
unsigned long ul_GainFactor[8]; // Gain Factor
|
||||
unsigned int w_GainValue[10];
|
||||
// End CG 15/02/02 Rev 1.0 -> Rev 1.1 : Add Header Type 1
|
||||
} str_Module;
|
||||
//END JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
|
||||
|
||||
//BEGIN JK 06.07.04: Management of sevrals boards
|
||||
typedef struct {
|
||||
INT i_CJCAvailable;
|
||||
INT i_CJCPolarity;
|
||||
INT i_CJCGain;
|
||||
INT i_InterruptFlag;
|
||||
INT i_ADDIDATAPolarity;
|
||||
INT i_ADDIDATAGain;
|
||||
INT i_AutoCalibration;
|
||||
INT i_ADDIDATAConversionTime;
|
||||
INT i_ADDIDATAConversionTimeUnit;
|
||||
INT i_ADDIDATAType;
|
||||
INT i_ChannelNo;
|
||||
INT i_ChannelCount;
|
||||
INT i_ScanType;
|
||||
INT i_FirstChannel;
|
||||
INT i_LastChannel;
|
||||
INT i_Sum;
|
||||
INT i_Offset;
|
||||
UINT ui_Channel_num;
|
||||
INT i_Count;
|
||||
INT i_Initialised;
|
||||
//UINT ui_InterruptChannelValue[96]; //Buffer
|
||||
UINT ui_InterruptChannelValue[144]; //Buffer
|
||||
BYTE b_StructInitialized;
|
||||
//Begin JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
|
||||
unsigned int ui_ScanValueArray[7 + 12]; // 7 is the maximal number of channels
|
||||
//End JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
|
||||
|
||||
//Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
|
||||
INT i_ConnectionType;
|
||||
INT i_NbrOfModule;
|
||||
str_Module s_Module[MAX_MODULE];
|
||||
//End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
|
||||
} str_BoardInfos;
|
||||
//END JK 06.07.04: Management of sevrals boards
|
||||
|
||||
// Hardware Layer functions for Apci3200
|
||||
|
||||
//AI
|
||||
|
||||
INT i_APCI3200_ConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
INT i_APCI3200_ReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
INT i_APCI3200_InsnWriteReleaseAnalogInput(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
INT i_APCI3200_InsnBits_AnalogInput_Test(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
INT i_APCI3200_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_subdevice *s);
|
||||
INT i_APCI3200_InterruptHandleEos(struct comedi_device *dev);
|
||||
INT i_APCI3200_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd);
|
||||
INT i_APCI3200_CommandAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s);
|
||||
INT i_APCI3200_ReadDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
//Interrupt
|
||||
void v_APCI3200_Interrupt(int irq, void *d);
|
||||
int i_APCI3200_InterruptHandleEos(struct comedi_device *dev);
|
||||
//Reset functions
|
||||
INT i_APCI3200_Reset(struct comedi_device *dev);
|
||||
|
||||
int i_APCI3200_ReadCJCCalOffset(struct comedi_device *dev, unsigned int *data);
|
||||
int i_APCI3200_ReadCJCValue(struct comedi_device *dev, unsigned int *data);
|
||||
int i_APCI3200_ReadCalibrationGainValue(struct comedi_device *dev, UINT *data);
|
||||
int i_APCI3200_ReadCalibrationOffsetValue(struct comedi_device *dev, UINT *data);
|
||||
int i_APCI3200_Read1AnalogInputChannel(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
int i_APCI3200_ReadCJCCalGain(struct comedi_device *dev, unsigned int *data);
|
|
@ -0,0 +1,742 @@
|
|||
/**
|
||||
@verbatim
|
||||
|
||||
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
|
||||
ADDI-DATA GmbH
|
||||
Dieselstrasse 3
|
||||
D-77833 Ottersweier
|
||||
Tel: +19(0)7223/9493-0
|
||||
Fax: +49(0)7223/9493-92
|
||||
http://www.addi-data-com
|
||||
info@addi-data.com
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
You shoud also find the complete GPL in the COPYING file accompanying this source code.
|
||||
|
||||
@endverbatim
|
||||
*/
|
||||
/*.
|
||||
|
||||
+-----------------------------------------------------------------------+
|
||||
| (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
|
||||
+-----------------------------------------------------------------------+
|
||||
| Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
|
||||
| Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
|
||||
+-------------------------------+---------------------------------------+
|
||||
| Project : APCI-3501 | Compiler : GCC |
|
||||
| Module name : hwdrv_apci3501.c| Version : 2.96 |
|
||||
+-------------------------------+---------------------------------------+
|
||||
| Project manager: Eric Stolz | Date : 02/12/2002 |
|
||||
+-------------------------------+---------------------------------------+
|
||||
| Description : Hardware Layer Acces For APCI-3501 |
|
||||
+-----------------------------------------------------------------------+
|
||||
| UPDATES |
|
||||
+----------+-----------+------------------------------------------------+
|
||||
| Date | Author | Description of updates |
|
||||
+----------+-----------+------------------------------------------------+
|
||||
| | | |
|
||||
| | | |
|
||||
| | | |
|
||||
+----------+-----------+------------------------------------------------+
|
||||
*/
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Included files |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
#include "hwdrv_apci3501.h"
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI3501_ReadDigitalInput |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s, |
|
||||
| struct comedi_insn *insn,unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Read value of the selected channel or port |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| UINT ui_NoOfChannels : No Of Channels To read |
|
||||
| UINT *data : Data Pointer to read status |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
INT i_APCI3501_ReadDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
UINT ui_Temp;
|
||||
UINT ui_NoOfChannel;
|
||||
ui_NoOfChannel = CR_CHAN(insn->chanspec);
|
||||
ui_Temp = data[0];
|
||||
*data = inl(devpriv->iobase + APCI3501_DIGITAL_IP);
|
||||
if (ui_Temp == 0) {
|
||||
*data = (*data >> ui_NoOfChannel) & 0x1;
|
||||
} //if (ui_Temp==0)
|
||||
else {
|
||||
if (ui_Temp == 1) {
|
||||
|
||||
*data = *data & 0x3;
|
||||
} //if (ui_Temp==1)
|
||||
else {
|
||||
printk("\nSpecified channel not supported \n");
|
||||
} //elseif (ui_Temp==1)
|
||||
} //elseif (ui_Temp==0)
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI3501_ConfigDigitalOutput |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s, |
|
||||
| struct comedi_insn *insn,unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Configures The Digital Output Subdevice. |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| UINT *data : Data Pointer contains |
|
||||
| configuration parameters as below |
|
||||
| |
|
||||
| data[1] : 1 Enable VCC Interrupt |
|
||||
| 0 Disable VCC Interrupt |
|
||||
| data[2] : 1 Enable CC Interrupt |
|
||||
| 0 Disable CC Interrupt |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
int i_APCI3501_ConfigDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
|
||||
if ((data[0] != 0) && (data[0] != 1)) {
|
||||
comedi_error(dev,
|
||||
"Not a valid Data !!! ,Data should be 1 or 0\n");
|
||||
return -EINVAL;
|
||||
} //if ( (data[0]!=0) && (data[0]!=1) )
|
||||
if (data[0]) {
|
||||
devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
|
||||
} // if (data[0])
|
||||
else {
|
||||
devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
|
||||
} //else if (data[0])
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI3501_WriteDigitalOutput |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s, |
|
||||
| struct comedi_insn *insn,unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : writes To the digital Output Subdevice |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| struct comedi_subdevice *s : Subdevice Pointer |
|
||||
| struct comedi_insn *insn : Insn Structure Pointer |
|
||||
| unsigned int *data : Data Pointer contains |
|
||||
| configuration parameters as below |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
INT i_APCI3501_WriteDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
UINT ui_Temp, ui_Temp1;
|
||||
UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
|
||||
if (devpriv->b_OutputMemoryStatus) {
|
||||
ui_Temp = inl(devpriv->iobase + APCI3501_DIGITAL_OP);
|
||||
} //if(devpriv->b_OutputMemoryStatus )
|
||||
else {
|
||||
ui_Temp = 0;
|
||||
} //if(devpriv->b_OutputMemoryStatus )
|
||||
if (data[3] == 0) {
|
||||
if (data[1] == 0) {
|
||||
data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
|
||||
outl(data[0], devpriv->iobase + APCI3501_DIGITAL_OP);
|
||||
} //if(data[1]==0)
|
||||
else {
|
||||
if (data[1] == 1) {
|
||||
data[0] = (data[0] << (2 * data[2])) | ui_Temp;
|
||||
outl(data[0],
|
||||
devpriv->iobase + APCI3501_DIGITAL_OP);
|
||||
} // if(data[1]==1)
|
||||
else {
|
||||
printk("\nSpecified channel not supported\n");
|
||||
} //else if(data[1]==1)
|
||||
} //elseif(data[1]==0)
|
||||
} //if(data[3]==0)
|
||||
else {
|
||||
if (data[3] == 1) {
|
||||
if (data[1] == 0) {
|
||||
data[0] = ~data[0] & 0x1;
|
||||
ui_Temp1 = 1;
|
||||
ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
|
||||
ui_Temp = ui_Temp | ui_Temp1;
|
||||
data[0] =
|
||||
(data[0] << ui_NoOfChannel) ^
|
||||
0xffffffff;
|
||||
data[0] = data[0] & ui_Temp;
|
||||
outl(data[0],
|
||||
devpriv->iobase + APCI3501_DIGITAL_OP);
|
||||
} //if(data[1]==0)
|
||||
else {
|
||||
if (data[1] == 1) {
|
||||
data[0] = ~data[0] & 0x3;
|
||||
ui_Temp1 = 3;
|
||||
ui_Temp1 = ui_Temp1 << 2 * data[2];
|
||||
ui_Temp = ui_Temp | ui_Temp1;
|
||||
data[0] =
|
||||
((data[0] << (2 *
|
||||
data[2])) ^
|
||||
0xffffffff) & ui_Temp;
|
||||
outl(data[0],
|
||||
devpriv->iobase +
|
||||
APCI3501_DIGITAL_OP);
|
||||
} // if(data[1]==1)
|
||||
else {
|
||||
printk("\nSpecified channel not supported\n");
|
||||
} //else if(data[1]==1)
|
||||
} //elseif(data[1]==0)
|
||||
} //if(data[3]==1);
|
||||
else {
|
||||
printk("\nSpecified functionality does not exist\n");
|
||||
return -EINVAL;
|
||||
} //if else data[3]==1)
|
||||
} //if else data[3]==0)
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI3501_ReadDigitalOutput |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s, |
|
||||
| struct comedi_insn *insn,unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Read value of the selected channel or port |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| UINT ui_NoOfChannels : No Of Channels To read |
|
||||
| UINT *data : Data Pointer to read status |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
INT i_APCI3501_ReadDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
UINT ui_Temp;
|
||||
UINT ui_NoOfChannel;
|
||||
|
||||
ui_NoOfChannel = CR_CHAN(insn->chanspec);
|
||||
ui_Temp = data[0];
|
||||
*data = inl(devpriv->iobase + APCI3501_DIGITAL_OP);
|
||||
if (ui_Temp == 0) {
|
||||
*data = (*data >> ui_NoOfChannel) & 0x1;
|
||||
} // if (ui_Temp==0)
|
||||
else {
|
||||
if (ui_Temp == 1) {
|
||||
*data = *data & 0x3;
|
||||
|
||||
} // if (ui_Temp==1)
|
||||
else {
|
||||
printk("\nSpecified channel not supported \n");
|
||||
} // else if (ui_Temp==1)
|
||||
} // else if (ui_Temp==0)
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI3501_ConfigAnalogOutput |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s, |
|
||||
| struct comedi_insn *insn,unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Configures The Analog Output Subdevice |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| struct comedi_subdevice *s : Subdevice Pointer |
|
||||
| struct comedi_insn *insn : Insn Structure Pointer |
|
||||
| unsigned int *data : Data Pointer contains |
|
||||
| configuration parameters as below |
|
||||
| |
|
||||
| data[0] : Voltage Mode |
|
||||
| 0:Mode 0 |
|
||||
| 1:Mode 1 |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
INT i_APCI3501_ConfigAnalogOutput(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
outl(data[0],
|
||||
devpriv->iobase + APCI3501_ANALOG_OUTPUT +
|
||||
APCI3501_AO_VOLT_MODE);
|
||||
|
||||
if (data[0]) {
|
||||
devpriv->b_InterruptMode = MODE1;
|
||||
} else {
|
||||
devpriv->b_InterruptMode = MODE0;
|
||||
}
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI3501_WriteAnalogOutput |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s, |
|
||||
| struct comedi_insn *insn,unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Writes To the Selected Anlog Output Channel |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| struct comedi_subdevice *s : Subdevice Pointer |
|
||||
| struct comedi_insn *insn : Insn Structure Pointer |
|
||||
| unsigned int *data : Data Pointer contains |
|
||||
| configuration parameters as below |
|
||||
| |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
INT i_APCI3501_WriteAnalogOutput(struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
ULONG ul_Command1 = 0, ul_Channel_no, ul_Polarity, ul_DAC_Ready = 0;;
|
||||
|
||||
ul_Channel_no = CR_CHAN(insn->chanspec);
|
||||
|
||||
if (devpriv->b_InterruptMode == MODE1) {
|
||||
ul_Polarity = 0x80000000;
|
||||
if ((*data < 0) || (*data > 16384)) {
|
||||
printk("\nIn WriteAnalogOutput :: Not Valid Data\n");
|
||||
}
|
||||
|
||||
} // end if(devpriv->b_InterruptMode==MODE1)
|
||||
else {
|
||||
ul_Polarity = 0;
|
||||
if ((*data < 0) || (*data > 8192)) {
|
||||
printk("\nIn WriteAnalogOutput :: Not Valid Data\n");
|
||||
}
|
||||
|
||||
} // end else
|
||||
|
||||
if ((ul_Channel_no < 0) || (ul_Channel_no > 7)) {
|
||||
printk("\nIn WriteAnalogOutput :: Not Valid Channel\n");
|
||||
} // end if((ul_Channel_no<0)||(ul_Channel_no>7))
|
||||
|
||||
ul_DAC_Ready = inl(devpriv->iobase + APCI3501_ANALOG_OUTPUT);
|
||||
|
||||
while (ul_DAC_Ready == 0) {
|
||||
ul_DAC_Ready = inl(devpriv->iobase + APCI3501_ANALOG_OUTPUT);
|
||||
ul_DAC_Ready = (ul_DAC_Ready >> 8) & 1;
|
||||
}
|
||||
|
||||
if (ul_DAC_Ready) {
|
||||
// Output the Value on the output channels.
|
||||
ul_Command1 =
|
||||
(ULONG) ((ULONG) (ul_Channel_no & 0xFF) |
|
||||
(ULONG) ((*data << 0x8) & 0x7FFFFF00L) |
|
||||
(ULONG) (ul_Polarity));
|
||||
outl(ul_Command1,
|
||||
devpriv->iobase + APCI3501_ANALOG_OUTPUT +
|
||||
APCI3501_AO_PROG);
|
||||
}
|
||||
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI3501_ConfigTimerCounterWatchdog |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s, |
|
||||
| struct comedi_insn *insn,unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Configures The Timer , Counter or Watchdog |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| UINT *data : Data Pointer contains |
|
||||
| configuration parameters as below |
|
||||
| |
|
||||
| data[0] : 0 Configure As Timer |
|
||||
| 1 Configure As Counter |
|
||||
| 2 Configure As Watchdog |
|
||||
| data[1] : 1 Enable Interrupt |
|
||||
| 0 Disable Interrupt |
|
||||
| data[2] : Time Unit |
|
||||
| data[3] : Reload Value |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
INT i_APCI3501_ConfigTimerCounterWatchdog(struct comedi_device * dev,
|
||||
struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
ULONG ul_Command1 = 0;
|
||||
devpriv->tsk_Current = current;
|
||||
if (data[0] == ADDIDATA_WATCHDOG) {
|
||||
|
||||
devpriv->b_TimerSelectMode = ADDIDATA_WATCHDOG;
|
||||
//Disable the watchdog
|
||||
outl(0x0, devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG); //disable Wa
|
||||
|
||||
if (data[1] == 1) {
|
||||
//Enable TIMER int & DISABLE ALL THE OTHER int SOURCES
|
||||
outl(0x02,
|
||||
devpriv->iobase + APCI3501_WATCHDOG +
|
||||
APCI3501_TCW_PROG);
|
||||
} else {
|
||||
outl(0x0, devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG); //disable Timer interrupt
|
||||
}
|
||||
|
||||
//Loading the Timebase value
|
||||
outl(data[2],
|
||||
devpriv->iobase + APCI3501_WATCHDOG +
|
||||
APCI3501_TCW_TIMEBASE);
|
||||
|
||||
//Loading the Reload value
|
||||
outl(data[3],
|
||||
devpriv->iobase + APCI3501_WATCHDOG +
|
||||
APCI3501_TCW_RELOAD_VALUE);
|
||||
//Set the mode
|
||||
ul_Command1 = inl(devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG) | 0xFFF819E0UL; //e2->e0
|
||||
outl(ul_Command1,
|
||||
devpriv->iobase + APCI3501_WATCHDOG +
|
||||
APCI3501_TCW_PROG);
|
||||
} //end if(data[0]==ADDIDATA_WATCHDOG)
|
||||
|
||||
else if (data[0] == ADDIDATA_TIMER) {
|
||||
//First Stop The Timer
|
||||
ul_Command1 =
|
||||
inl(devpriv->iobase + APCI3501_WATCHDOG +
|
||||
APCI3501_TCW_PROG);
|
||||
ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
|
||||
outl(ul_Command1, devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG); //Stop The Timer
|
||||
devpriv->b_TimerSelectMode = ADDIDATA_TIMER;
|
||||
if (data[1] == 1) {
|
||||
//Enable TIMER int & DISABLE ALL THE OTHER int SOURCES
|
||||
outl(0x02,
|
||||
devpriv->iobase + APCI3501_WATCHDOG +
|
||||
APCI3501_TCW_PROG);
|
||||
} else {
|
||||
outl(0x0, devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG); //disable Timer interrupt
|
||||
}
|
||||
|
||||
// Loading Timebase
|
||||
outl(data[2],
|
||||
devpriv->iobase + APCI3501_WATCHDOG +
|
||||
APCI3501_TCW_TIMEBASE);
|
||||
|
||||
//Loading the Reload value
|
||||
outl(data[3],
|
||||
devpriv->iobase + APCI3501_WATCHDOG +
|
||||
APCI3501_TCW_RELOAD_VALUE);
|
||||
|
||||
// printk ("\nTimer Address :: %x\n", (devpriv->iobase+APCI3501_WATCHDOG));
|
||||
ul_Command1 =
|
||||
inl(devpriv->iobase + APCI3501_WATCHDOG +
|
||||
APCI3501_TCW_PROG);
|
||||
ul_Command1 =
|
||||
(ul_Command1 & 0xFFF719E2UL) | 2UL << 13UL | 0x10UL;
|
||||
outl(ul_Command1, devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG); //mode 2
|
||||
|
||||
} //end if(data[0]==ADDIDATA_TIMER)
|
||||
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI3501_StartStopWriteTimerCounterWatchdog |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s, |
|
||||
| struct comedi_insn *insn,unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Start / Stop The Selected Timer , Counter or Watchdog |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| UINT *data : Data Pointer contains |
|
||||
| configuration parameters as below |
|
||||
| |
|
||||
| data[0] : 0 Timer |
|
||||
| 1 Counter |
|
||||
| 2 Watchdog | | data[1] : 1 Start |
|
||||
| 0 Stop | 2 Trigger |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
int i_APCI3501_StartStopWriteTimerCounterWatchdog(struct comedi_device * dev,
|
||||
struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
ULONG ul_Command1 = 0;
|
||||
int i_Temp;
|
||||
if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
|
||||
|
||||
if (data[1] == 1) {
|
||||
ul_Command1 =
|
||||
inl(devpriv->iobase + APCI3501_WATCHDOG +
|
||||
APCI3501_TCW_PROG);
|
||||
ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL;
|
||||
//Enable the Watchdog
|
||||
outl(ul_Command1,
|
||||
devpriv->iobase + APCI3501_WATCHDOG +
|
||||
APCI3501_TCW_PROG);
|
||||
}
|
||||
|
||||
else if (data[1] == 0) //Stop The Watchdog
|
||||
{
|
||||
//Stop The Watchdog
|
||||
ul_Command1 =
|
||||
inl(devpriv->iobase + APCI3501_WATCHDOG +
|
||||
APCI3501_TCW_PROG);
|
||||
ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
|
||||
outl(0x0,
|
||||
devpriv->iobase + APCI3501_WATCHDOG +
|
||||
APCI3501_TCW_PROG);
|
||||
} else if (data[1] == 2) {
|
||||
ul_Command1 =
|
||||
inl(devpriv->iobase + APCI3501_WATCHDOG +
|
||||
APCI3501_TCW_PROG);
|
||||
ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x200UL;
|
||||
outl(ul_Command1,
|
||||
devpriv->iobase + APCI3501_WATCHDOG +
|
||||
APCI3501_TCW_PROG);
|
||||
} //if(data[1]==2)
|
||||
} // end if (devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG)
|
||||
|
||||
if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) {
|
||||
if (data[1] == 1) {
|
||||
|
||||
ul_Command1 =
|
||||
inl(devpriv->iobase + APCI3501_WATCHDOG +
|
||||
APCI3501_TCW_PROG);
|
||||
ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL;
|
||||
//Enable the Timer
|
||||
outl(ul_Command1,
|
||||
devpriv->iobase + APCI3501_WATCHDOG +
|
||||
APCI3501_TCW_PROG);
|
||||
} else if (data[1] == 0) {
|
||||
//Stop The Timer
|
||||
ul_Command1 =
|
||||
inl(devpriv->iobase + APCI3501_WATCHDOG +
|
||||
APCI3501_TCW_PROG);
|
||||
ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
|
||||
outl(ul_Command1,
|
||||
devpriv->iobase + APCI3501_WATCHDOG +
|
||||
APCI3501_TCW_PROG);
|
||||
}
|
||||
|
||||
else if (data[1] == 2) {
|
||||
//Trigger the Timer
|
||||
ul_Command1 =
|
||||
inl(devpriv->iobase + APCI3501_WATCHDOG +
|
||||
APCI3501_TCW_PROG);
|
||||
ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x200UL;
|
||||
outl(ul_Command1,
|
||||
devpriv->iobase + APCI3501_WATCHDOG +
|
||||
APCI3501_TCW_PROG);
|
||||
}
|
||||
|
||||
} // end if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER)
|
||||
i_Temp = inl(devpriv->iobase + APCI3501_WATCHDOG +
|
||||
APCI3501_TCW_TRIG_STATUS) & 0x1;
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI3501_ReadTimerCounterWatchdog |
|
||||
| (struct comedi_device *dev,struct comedi_subdevice *s, |
|
||||
| struct comedi_insn *insn,unsigned int *data) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Read The Selected Timer , Counter or Watchdog |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : struct comedi_device *dev : Driver handle |
|
||||
| UINT *data : Data Pointer contains |
|
||||
| configuration parameters as below |
|
||||
| |
|
||||
| data[0] : 0 Timer |
|
||||
| 1 Counter |
|
||||
| 2 Watchdog | | data[1] : Timer Counter Watchdog Number |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
int i_APCI3501_ReadTimerCounterWatchdog(struct comedi_device * dev,
|
||||
struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
|
||||
{
|
||||
|
||||
if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
|
||||
data[0] =
|
||||
inl(devpriv->iobase + APCI3501_WATCHDOG +
|
||||
APCI3501_TCW_TRIG_STATUS) & 0x1;
|
||||
data[1] = inl(devpriv->iobase + APCI3501_WATCHDOG);
|
||||
} // end if (devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG)
|
||||
|
||||
else if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) {
|
||||
data[0] =
|
||||
inl(devpriv->iobase + APCI3501_WATCHDOG +
|
||||
APCI3501_TCW_TRIG_STATUS) & 0x1;
|
||||
data[1] = inl(devpriv->iobase + APCI3501_WATCHDOG);
|
||||
} // end if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER)
|
||||
|
||||
else if ((devpriv->b_TimerSelectMode != ADDIDATA_TIMER)
|
||||
&& (devpriv->b_TimerSelectMode != ADDIDATA_WATCHDOG)) {
|
||||
printk("\nIn ReadTimerCounterWatchdog :: Invalid Subdevice \n");
|
||||
}
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : int i_APCI3501_Reset(struct comedi_device *dev) |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task :Resets the registers of the card |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
int i_APCI3501_Reset(struct comedi_device * dev)
|
||||
{
|
||||
int i_Count = 0, i_temp = 0;
|
||||
ULONG ul_Command1 = 0, ul_Polarity, ul_DAC_Ready = 0;
|
||||
outl(0x0, devpriv->iobase + APCI3501_DIGITAL_OP);
|
||||
outl(1, devpriv->iobase + APCI3501_ANALOG_OUTPUT +
|
||||
APCI3501_AO_VOLT_MODE);
|
||||
|
||||
ul_Polarity = 0x80000000;
|
||||
|
||||
for (i_Count = 0; i_Count <= 7; i_Count++) {
|
||||
ul_DAC_Ready = inl(devpriv->iobase + APCI3501_ANALOG_OUTPUT);
|
||||
|
||||
while (ul_DAC_Ready == 0) {
|
||||
ul_DAC_Ready =
|
||||
inl(devpriv->iobase + APCI3501_ANALOG_OUTPUT);
|
||||
ul_DAC_Ready = (ul_DAC_Ready >> 8) & 1;
|
||||
}
|
||||
|
||||
if (ul_DAC_Ready) {
|
||||
// Output the Value on the output channels.
|
||||
ul_Command1 =
|
||||
(ULONG) ((ULONG) (i_Count & 0xFF) |
|
||||
(ULONG) ((i_temp << 0x8) & 0x7FFFFF00L) |
|
||||
(ULONG) (ul_Polarity));
|
||||
outl(ul_Command1,
|
||||
devpriv->iobase + APCI3501_ANALOG_OUTPUT +
|
||||
APCI3501_AO_PROG);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------------+
|
||||
| Function Name : static void v_APCI3501_Interrupt |
|
||||
| (int irq , void *d) |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Task : Interrupt processing Routine |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Input Parameters : int irq : irq number |
|
||||
| void *d : void pointer |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Output Parameters : -- |
|
||||
+----------------------------------------------------------------------------+
|
||||
| Return Value : TRUE : No error occur |
|
||||
| : FALSE : Error occur. Return the error |
|
||||
| |
|
||||
+----------------------------------------------------------------------------+
|
||||
*/
|
||||
void v_APCI3501_Interrupt(int irq, void *d)
|
||||
{
|
||||
int i_temp;
|
||||
struct comedi_device *dev = d;
|
||||
unsigned int ui_Timer_AOWatchdog;
|
||||
unsigned long ul_Command1;
|
||||
// Disable Interrupt
|
||||
ul_Command1 =
|
||||
inl(devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG);
|
||||
|
||||
ul_Command1 = (ul_Command1 & 0xFFFFF9FDul);
|
||||
outl(ul_Command1,
|
||||
devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG);
|
||||
|
||||
ui_Timer_AOWatchdog =
|
||||
inl(devpriv->iobase + APCI3501_WATCHDOG +
|
||||
APCI3501_TCW_IRQ) & 0x1;
|
||||
|
||||
if ((!ui_Timer_AOWatchdog)) {
|
||||
comedi_error(dev, "IRQ from unknow source");
|
||||
return;
|
||||
}
|
||||
|
||||
// Enable Interrupt
|
||||
//Send a signal to from kernel to user space
|
||||
send_sig(SIGIO, devpriv->tsk_Current, 0);
|
||||
ul_Command1 =
|
||||
inl(devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG);
|
||||
ul_Command1 = ((ul_Command1 & 0xFFFFF9FDul) | 1 << 1);
|
||||
outl(ul_Command1,
|
||||
devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG);
|
||||
i_temp = inl(devpriv->iobase + APCI3501_WATCHDOG +
|
||||
APCI3501_TCW_TRIG_STATUS) & 0x1;
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
*
|
||||
* ADDI-DATA GmbH
|
||||
* Dieselstrasse 3
|
||||
* D-77833 Ottersweier
|
||||
* Tel: +19(0)7223/9493-0
|
||||
* Fax: +49(0)7223/9493-92
|
||||
* http://www.addi-data-com
|
||||
* info@addi-data.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*/
|
||||
|
||||
// Card Specific information
|
||||
#define APCI3501_BOARD_VENDOR_ID 0x15B8
|
||||
#define APCI3501_ADDRESS_RANGE 255
|
||||
|
||||
#define APCI3501_DIGITAL_IP 0x50
|
||||
#define APCI3501_DIGITAL_OP 0x40
|
||||
#define APCI3501_ANALOG_OUTPUT 0x00
|
||||
|
||||
//Analog Output related Defines
|
||||
#define APCI3501_AO_VOLT_MODE 0
|
||||
#define APCI3501_AO_PROG 4
|
||||
#define APCI3501_AO_TRIG_SCS 8
|
||||
#define UNIPOLAR 0
|
||||
#define BIPOLAR 1
|
||||
#define MODE0 0
|
||||
#define MODE1 1
|
||||
// ANALOG OUTPUT RANGE
|
||||
struct comedi_lrange range_apci3501_ao = { 2, {
|
||||
BIP_RANGE(10),
|
||||
UNI_RANGE(10)
|
||||
}
|
||||
};
|
||||
|
||||
//Watchdog Related Defines
|
||||
|
||||
#define APCI3501_WATCHDOG 0x20
|
||||
#define APCI3501_TCW_SYNC_ENABLEDISABLE 0
|
||||
#define APCI3501_TCW_RELOAD_VALUE 4
|
||||
#define APCI3501_TCW_TIMEBASE 8
|
||||
#define APCI3501_TCW_PROG 12
|
||||
#define APCI3501_TCW_TRIG_STATUS 16
|
||||
#define APCI3501_TCW_IRQ 20
|
||||
#define APCI3501_TCW_WARN_TIMEVAL 24
|
||||
#define APCI3501_TCW_WARN_TIMEBASE 28
|
||||
#define ADDIDATA_TIMER 0
|
||||
#define ADDIDATA_WATCHDOG 2
|
||||
|
||||
// Hardware Layer functions for Apci3501
|
||||
|
||||
//AO
|
||||
INT i_APCI3501_ConfigAnalogOutput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
INT i_APCI3501_WriteAnalogOutput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
//DI
|
||||
// for di read
|
||||
//INT i_APCI3501_ReadDigitalInput(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data);
|
||||
|
||||
INT i_APCI3501_ReadDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
//DO
|
||||
int i_APCI3501_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
INT i_APCI3501_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
INT i_APCI3501_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
// TIMER
|
||||
// timer value is passed as u seconds
|
||||
INT i_APCI3501_ConfigTimerCounterWatchdog(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
int i_APCI3501_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
int i_APCI3501_ReadTimerCounterWatchdog(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
//Interrupt
|
||||
void v_APCI3501_Interrupt(int irq, void *d);
|
||||
|
||||
//Reset functions
|
||||
int i_APCI3501_Reset(struct comedi_device *dev);
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
|
||||
*
|
||||
* ADDI-DATA GmbH
|
||||
* Dieselstrasse 3
|
||||
* D-77833 Ottersweier
|
||||
* Tel: +19(0)7223/9493-0
|
||||
* Fax: +49(0)7223/9493-92
|
||||
* http://www.addi-data-com
|
||||
* info@addi-data.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*/
|
||||
|
||||
#ifndef COMEDI_SUBD_TTLIO
|
||||
#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */
|
||||
#endif
|
||||
|
||||
#ifndef ADDIDATA_ENABLE
|
||||
#define ADDIDATA_ENABLE 1
|
||||
#define ADDIDATA_DISABLE 0
|
||||
#endif
|
||||
|
||||
#define APCI3XXX_SINGLE 0
|
||||
#define APCI3XXX_DIFF 1
|
||||
#define APCI3XXX_CONFIGURATION 0
|
||||
|
||||
#define APCI3XXX_TTL_INIT_DIRECTION_PORT2 0
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
static const struct comedi_lrange range_apci3XXX_ai = { 8, {BIP_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(2),
|
||||
BIP_RANGE(1),
|
||||
UNI_RANGE(10),
|
||||
UNI_RANGE(5),
|
||||
UNI_RANGE(2),
|
||||
UNI_RANGE(1)}
|
||||
};
|
||||
|
||||
static const struct comedi_lrange range_apci3XXX_ttl = { 12, {BIP_RANGE(1),
|
||||
BIP_RANGE(1),
|
||||
BIP_RANGE(1),
|
||||
BIP_RANGE(1),
|
||||
BIP_RANGE(1),
|
||||
BIP_RANGE(1),
|
||||
BIP_RANGE(1),
|
||||
BIP_RANGE(1),
|
||||
BIP_RANGE(1),
|
||||
BIP_RANGE(1),
|
||||
BIP_RANGE(1),
|
||||
BIP_RANGE(1)}
|
||||
};
|
||||
|
||||
static const struct comedi_lrange range_apci3XXX_ao = { 2, {BIP_RANGE(10),
|
||||
UNI_RANGE(10)}
|
||||
};
|
||||
#endif
|
|
@ -0,0 +1,5 @@
|
|||
#define CONFIG_APCI_035 1
|
||||
|
||||
#define ADDIDATA_WATCHDOG 2 // Or shold it be something else
|
||||
|
||||
#include "addi-data/addi_common.c"
|
|
@ -0,0 +1,3 @@
|
|||
#define CONFIG_APCI_1032 1
|
||||
|
||||
#include "addi-data/addi_common.c"
|
|
@ -0,0 +1,3 @@
|
|||
#define CONFIG_APCI_1500 1
|
||||
|
||||
#include "addi-data/addi_common.c"
|
|
@ -0,0 +1,3 @@
|
|||
#define CONFIG_APCI_1516 1
|
||||
|
||||
#include "addi-data/addi_common.c"
|
|
@ -0,0 +1,3 @@
|
|||
#define CONFIG_APCI_1564 1
|
||||
|
||||
#include "addi-data/addi_common.c"
|
|
@ -0,0 +1,3 @@
|
|||
#define CONFIG_APCI_16XX 1
|
||||
|
||||
#include "addi-data/addi_common.c"
|
|
@ -0,0 +1,3 @@
|
|||
#define CONFIG_APCI_1710 1
|
||||
|
||||
#include "addi-data/addi_common.c"
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue