mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-02-05 21:03:14 -05:00
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: (641 commits) Staging: remove sxg driver Staging: remove heci driver Staging: remove at76_usb wireless driver. Staging: rspiusb: remove the driver Staging: meilhaus: remove the drivers Staging: remove me4000 driver. Staging: line6: ffzb returns an unsigned integer Staging: line6: pod.c: style cleanups Staging: iio: introduce missing kfree Staging: dream: introduce missing kfree Staging: comedi: addi-data: NULL dereference of amcc in v_pci_card_list_init() Staging: vt665x: fix built-in compiling Staging: rt3090: enable NATIVE_WPA_SUPPLICANT_SUPPORT option Staging: rt3090: port changes in WPA_MIX_PAIR_CIPHER to rt3090 Staging: rt3090: rename device from raX to wlanX Staging: rt3090: remove possible conflict with rt2860 Staging: rt2860/rt2870/rt3070/rt3090: fix compiler warning on x86_64 Staging: rt2860: add new device ids Staging: rt3090: add device id 1462:891a Staging: asus_oled: Cleaned up checkpatch issues. ...
This commit is contained in:
@@ -45,12 +45,6 @@ source "drivers/staging/et131x/Kconfig"
|
||||
|
||||
source "drivers/staging/slicoss/Kconfig"
|
||||
|
||||
source "drivers/staging/sxg/Kconfig"
|
||||
|
||||
source "drivers/staging/me4000/Kconfig"
|
||||
|
||||
source "drivers/staging/meilhaus/Kconfig"
|
||||
|
||||
source "drivers/staging/go7007/Kconfig"
|
||||
|
||||
source "drivers/staging/usbip/Kconfig"
|
||||
@@ -61,8 +55,6 @@ source "drivers/staging/wlan-ng/Kconfig"
|
||||
|
||||
source "drivers/staging/echo/Kconfig"
|
||||
|
||||
source "drivers/staging/at76_usb/Kconfig"
|
||||
|
||||
source "drivers/staging/poch/Kconfig"
|
||||
|
||||
source "drivers/staging/agnx/Kconfig"
|
||||
@@ -73,7 +65,7 @@ source "drivers/staging/rt2860/Kconfig"
|
||||
|
||||
source "drivers/staging/rt2870/Kconfig"
|
||||
|
||||
source "drivers/staging/rt3070/Kconfig"
|
||||
source "drivers/staging/rt3090/Kconfig"
|
||||
|
||||
source "drivers/staging/comedi/Kconfig"
|
||||
|
||||
@@ -87,16 +79,16 @@ source "drivers/staging/rtl8187se/Kconfig"
|
||||
|
||||
source "drivers/staging/rtl8192su/Kconfig"
|
||||
|
||||
source "drivers/staging/rspiusb/Kconfig"
|
||||
source "drivers/staging/rtl8192e/Kconfig"
|
||||
|
||||
source "drivers/staging/mimio/Kconfig"
|
||||
|
||||
source "drivers/staging/frontier/Kconfig"
|
||||
|
||||
source "drivers/staging/epl/Kconfig"
|
||||
|
||||
source "drivers/staging/android/Kconfig"
|
||||
|
||||
source "drivers/staging/dream/Kconfig"
|
||||
|
||||
source "drivers/staging/dst/Kconfig"
|
||||
|
||||
source "drivers/staging/pohmelfs/Kconfig"
|
||||
@@ -109,8 +101,6 @@ source "drivers/staging/phison/Kconfig"
|
||||
|
||||
source "drivers/staging/p9auth/Kconfig"
|
||||
|
||||
source "drivers/staging/heci/Kconfig"
|
||||
|
||||
source "drivers/staging/line6/Kconfig"
|
||||
|
||||
source "drivers/gpu/drm/radeon/Kconfig"
|
||||
@@ -119,13 +109,27 @@ source "drivers/staging/octeon/Kconfig"
|
||||
|
||||
source "drivers/staging/serqt_usb2/Kconfig"
|
||||
|
||||
source "drivers/staging/quatech_usb2/Kconfig"
|
||||
|
||||
source "drivers/staging/vt6655/Kconfig"
|
||||
|
||||
source "drivers/staging/vt6656/Kconfig"
|
||||
|
||||
source "drivers/staging/cpc-usb/Kconfig"
|
||||
|
||||
source "drivers/staging/pata_rdc/Kconfig"
|
||||
|
||||
source "drivers/staging/udlfb/Kconfig"
|
||||
|
||||
source "drivers/staging/hv/Kconfig"
|
||||
|
||||
source "drivers/staging/vme/Kconfig"
|
||||
|
||||
source "drivers/staging/rar/Kconfig"
|
||||
|
||||
source "drivers/staging/sep/Kconfig"
|
||||
|
||||
source "drivers/staging/iio/Kconfig"
|
||||
|
||||
source "drivers/staging/cowloop/Kconfig"
|
||||
|
||||
endif # !STAGING_EXCLUDE_BUILD
|
||||
endif # STAGING
|
||||
|
||||
@@ -5,43 +5,45 @@ obj-$(CONFIG_STAGING) += staging.o
|
||||
|
||||
obj-$(CONFIG_ET131X) += et131x/
|
||||
obj-$(CONFIG_SLICOSS) += slicoss/
|
||||
obj-$(CONFIG_SXG) += sxg/
|
||||
obj-$(CONFIG_ME4000) += me4000/
|
||||
obj-$(CONFIG_MEILHAUS) += meilhaus/
|
||||
obj-$(CONFIG_VIDEO_GO7007) += go7007/
|
||||
obj-$(CONFIG_USB_IP_COMMON) += usbip/
|
||||
obj-$(CONFIG_W35UND) += winbond/
|
||||
obj-$(CONFIG_PRISM2_USB) += wlan-ng/
|
||||
obj-$(CONFIG_ECHO) += echo/
|
||||
obj-$(CONFIG_USB_ATMEL) += at76_usb/
|
||||
obj-$(CONFIG_POCH) += poch/
|
||||
obj-$(CONFIG_AGNX) += agnx/
|
||||
obj-$(CONFIG_OTUS) += otus/
|
||||
obj-$(CONFIG_RT2860) += rt2860/
|
||||
obj-$(CONFIG_RT2870) += rt2870/
|
||||
obj-$(CONFIG_RT3070) += rt3070/
|
||||
obj-$(CONFIG_RT3090) += rt3090/
|
||||
obj-$(CONFIG_COMEDI) += comedi/
|
||||
obj-$(CONFIG_ASUS_OLED) += asus_oled/
|
||||
obj-$(CONFIG_PANEL) += panel/
|
||||
obj-$(CONFIG_ALTERA_PCIE_CHDMA) += altpciechdma/
|
||||
obj-$(CONFIG_RTL8187SE) += rtl8187se/
|
||||
obj-$(CONFIG_RTL8192SU) += rtl8192su/
|
||||
obj-$(CONFIG_USB_RSPI) += rspiusb/
|
||||
obj-$(CONFIG_RTL8192E) += rtl8192e/
|
||||
obj-$(CONFIG_INPUT_MIMIO) += mimio/
|
||||
obj-$(CONFIG_TRANZPORT) += frontier/
|
||||
obj-$(CONFIG_EPL) += epl/
|
||||
obj-$(CONFIG_ANDROID) += android/
|
||||
obj-$(CONFIG_ANDROID) += dream/
|
||||
obj-$(CONFIG_DST) += dst/
|
||||
obj-$(CONFIG_POHMELFS) += pohmelfs/
|
||||
obj-$(CONFIG_STLC45XX) += stlc45xx/
|
||||
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_QUATECH2) += serqt_usb2/
|
||||
obj-$(CONFIG_USB_SERIAL_QUATECH_USB2) += quatech_usb2/
|
||||
obj-$(CONFIG_OCTEON_ETHERNET) += octeon/
|
||||
obj-$(CONFIG_VT6655) += vt6655/
|
||||
obj-$(CONFIG_VT6656) += vt6656/
|
||||
obj-$(CONFIG_USB_CPC) += cpc-usb/
|
||||
obj-$(CONFIG_RDC_17F3101X) += pata_rdc/
|
||||
obj-$(CONFIG_FB_UDL) += udlfb/
|
||||
obj-$(CONFIG_HYPERV) += hv/
|
||||
obj-$(CONFIG_VME_BUS) += vme/
|
||||
obj-$(CONFIG_RAR_REGISTER) += rar/
|
||||
obj-$(CONFIG_DX_SEP) += sep/
|
||||
obj-$(CONFIG_IIO) += iio/
|
||||
obj-$(CONFIG_COWLOOP) += cowloop/
|
||||
|
||||
@@ -280,7 +280,7 @@ 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);
|
||||
/* flush_workqueue(priv->hw->workqueue); */
|
||||
/* cancel_delayed_work_sync(&priv->periodic_work); */
|
||||
unfill_rings(priv);
|
||||
rings_free(priv);
|
||||
|
||||
@@ -550,7 +550,7 @@ static int __devinit dma_test(struct ape_dev *ape, struct pci_dev *dev)
|
||||
#if 0
|
||||
*(u32 *)(buffer_virt + i) = i / PAGE_SIZE + 1;
|
||||
#else
|
||||
*(u32 *)(buffer_virt + i) = (buffer_virt + i);
|
||||
*(u32 *)(buffer_virt + i) = (u32)(unsigned long)(buffer_virt + i);
|
||||
#endif
|
||||
#if 0
|
||||
compare((u32 *)buffer_virt, (u32 *)(buffer_virt + 2 * PAGE_SIZE), 8192);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,20 @@
|
||||
/* drivers/misc/lowmemorykiller.c
|
||||
*
|
||||
* The lowmemorykiller driver lets user-space specify a set of memory thresholds
|
||||
* where processes with a range of oom_adj values will get killed. Specify the
|
||||
* minimum oom_adj values in /sys/module/lowmemorykiller/parameters/adj and the
|
||||
* number of free pages in /sys/module/lowmemorykiller/parameters/minfree. Both
|
||||
* files take a comma separated list of numbers in ascending order.
|
||||
*
|
||||
* For example, write "0,8" to /sys/module/lowmemorykiller/parameters/adj and
|
||||
* "1024,4096" to /sys/module/lowmemorykiller/parameters/minfree to kill processes
|
||||
* with a oom_adj value of 8 or higher when the free memory drops below 4096 pages
|
||||
* and kill processes with a oom_adj value of 0 or higher when the free memory
|
||||
* drops below 1024 pages.
|
||||
*
|
||||
* The driver considers memory used for caches to be free, but if a large
|
||||
* percentage of the cached memory is locked this can be very inaccurate
|
||||
* and processes may not get killed until the normal oom killer is triggered.
|
||||
*
|
||||
* Copyright (C) 2007-2008 Google, Inc.
|
||||
*
|
||||
@@ -19,12 +35,6 @@
|
||||
#include <linux/oom.h>
|
||||
#include <linux/sched.h>
|
||||
|
||||
static int lowmem_shrink(int nr_to_scan, gfp_t gfp_mask);
|
||||
|
||||
static struct shrinker lowmem_shrinker = {
|
||||
.shrink = lowmem_shrink,
|
||||
.seeks = DEFAULT_SEEKS * 16
|
||||
};
|
||||
static uint32_t lowmem_debug_level = 2;
|
||||
static int lowmem_adj[6] = {
|
||||
0,
|
||||
@@ -47,13 +57,6 @@ static int lowmem_minfree_size = 4;
|
||||
printk(x); \
|
||||
} while (0)
|
||||
|
||||
module_param_named(cost, lowmem_shrinker.seeks, int, S_IRUGO | S_IWUSR);
|
||||
module_param_array_named(adj, lowmem_adj, int, &lowmem_adj_size,
|
||||
S_IRUGO | S_IWUSR);
|
||||
module_param_array_named(minfree, lowmem_minfree, uint, &lowmem_minfree_size,
|
||||
S_IRUGO | S_IWUSR);
|
||||
module_param_named(debug_level, lowmem_debug_level, uint, S_IRUGO | S_IWUSR);
|
||||
|
||||
static int lowmem_shrink(int nr_to_scan, gfp_t gfp_mask)
|
||||
{
|
||||
struct task_struct *p;
|
||||
@@ -140,6 +143,11 @@ static int lowmem_shrink(int nr_to_scan, gfp_t gfp_mask)
|
||||
return rem;
|
||||
}
|
||||
|
||||
static struct shrinker lowmem_shrinker = {
|
||||
.shrink = lowmem_shrink,
|
||||
.seeks = DEFAULT_SEEKS * 16
|
||||
};
|
||||
|
||||
static int __init lowmem_init(void)
|
||||
{
|
||||
register_shrinker(&lowmem_shrinker);
|
||||
@@ -151,6 +159,13 @@ static void __exit lowmem_exit(void)
|
||||
unregister_shrinker(&lowmem_shrinker);
|
||||
}
|
||||
|
||||
module_param_named(cost, lowmem_shrinker.seeks, int, S_IRUGO | S_IWUSR);
|
||||
module_param_array_named(adj, lowmem_adj, int, &lowmem_adj_size,
|
||||
S_IRUGO | S_IWUSR);
|
||||
module_param_array_named(minfree, lowmem_minfree, uint, &lowmem_minfree_size,
|
||||
S_IRUGO | S_IWUSR);
|
||||
module_param_named(debug_level, lowmem_debug_level, uint, S_IRUGO | S_IWUSR);
|
||||
|
||||
module_init(lowmem_init);
|
||||
module_exit(lowmem_exit);
|
||||
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
The lowmemorykiller driver lets user-space specify a set of memory thresholds
|
||||
where processes with a range of oom_adj values will get killed. Specify the
|
||||
minimum oom_adj values in /sys/module/lowmemorykiller/parameters/adj and the
|
||||
number of free pages in /sys/module/lowmemorykiller/parameters/minfree. Both
|
||||
files take a comma separated list of numbers in ascending order.
|
||||
|
||||
For example, write "0,8" to /sys/module/lowmemorykiller/parameters/adj and
|
||||
"1024,4096" to /sys/module/lowmemorykiller/parameters/minfree to kill processes
|
||||
with a oom_adj value of 8 or higher when the free memory drops below 4096 pages
|
||||
and kill processes with a oom_adj value of 0 or higher when the free memory
|
||||
drops below 1024 pages.
|
||||
|
||||
The driver considers memory used for caches to be free, but if a large
|
||||
percentage of the cached memory is locked this can be very inaccurate
|
||||
and processes may not get killed until the normal oom killer is triggered.
|
||||
|
||||
@@ -63,26 +63,31 @@ static uint start_off;
|
||||
|
||||
module_param(start_off, uint, 0644);
|
||||
|
||||
MODULE_PARM_DESC(start_off, "Set to 1 to switch off OLED display after it is attached");
|
||||
MODULE_PARM_DESC(start_off,
|
||||
"Set to 1 to switch off OLED display after it is attached");
|
||||
|
||||
typedef enum {
|
||||
enum oled_pack_mode{
|
||||
PACK_MODE_G1,
|
||||
PACK_MODE_G50,
|
||||
PACK_MODE_LAST
|
||||
} oled_pack_mode_t;
|
||||
};
|
||||
|
||||
struct oled_dev_desc_str {
|
||||
uint16_t idVendor;
|
||||
uint16_t idProduct;
|
||||
uint16_t devWidth; // width of display
|
||||
oled_pack_mode_t packMode; // formula to be used while packing the picture
|
||||
/* width of display */
|
||||
uint16_t devWidth;
|
||||
/* formula to be used while packing the picture */
|
||||
enum oled_pack_mode packMode;
|
||||
const char *devDesc;
|
||||
};
|
||||
|
||||
/* table of devices that work with this driver */
|
||||
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?)
|
||||
/* Asus G1/G2 (and variants)*/
|
||||
{ USB_DEVICE(0x0b05, 0x1726) },
|
||||
/* Asus G50V (and possibly others - G70? G71?)*/
|
||||
{ USB_DEVICE(0x0b05, 0x175b) },
|
||||
{ },
|
||||
};
|
||||
|
||||
@@ -95,20 +100,6 @@ static struct oled_dev_desc_str oled_dev_desc_table[] = {
|
||||
|
||||
MODULE_DEVICE_TABLE(usb, id_table);
|
||||
|
||||
#define SETUP_PACKET_HEADER(packet, val1, val2, val3, val4, val5, val6, val7) \
|
||||
do { \
|
||||
memset(packet, 0, sizeof(struct asus_oled_header)); \
|
||||
packet->header.magic1 = 0x55; \
|
||||
packet->header.magic2 = 0xaa; \
|
||||
packet->header.flags = val1; \
|
||||
packet->header.value3 = val2; \
|
||||
packet->header.buffer1 = val3; \
|
||||
packet->header.buffer2 = val4; \
|
||||
packet->header.value6 = val5; \
|
||||
packet->header.value7 = val6; \
|
||||
packet->header.value8 = val7; \
|
||||
} while (0);
|
||||
|
||||
struct asus_oled_header {
|
||||
uint8_t magic1;
|
||||
uint8_t magic2;
|
||||
@@ -128,10 +119,10 @@ struct asus_oled_packet {
|
||||
} __attribute((packed));
|
||||
|
||||
struct asus_oled_dev {
|
||||
struct usb_device * udev;
|
||||
struct usb_device *udev;
|
||||
uint8_t pic_mode;
|
||||
uint16_t dev_width;
|
||||
oled_pack_mode_t pack_mode;
|
||||
enum oled_pack_mode pack_mode;
|
||||
size_t height;
|
||||
size_t width;
|
||||
size_t x_shift;
|
||||
@@ -144,12 +135,28 @@ struct asus_oled_dev {
|
||||
struct device *dev;
|
||||
};
|
||||
|
||||
static void setup_packet_header(struct asus_oled_packet *packet, char flags,
|
||||
char value3, char buffer1, char buffer2, char value6,
|
||||
char value7, char value8)
|
||||
{
|
||||
memset(packet, 0, sizeof(struct asus_oled_header));
|
||||
packet->header.magic1 = 0x55;
|
||||
packet->header.magic2 = 0xaa;
|
||||
packet->header.flags = flags;
|
||||
packet->header.value3 = value3;
|
||||
packet->header.buffer1 = buffer1;
|
||||
packet->header.buffer2 = buffer2;
|
||||
packet->header.value6 = value6;
|
||||
packet->header.value7 = value7;
|
||||
packet->header.value8 = value8;
|
||||
}
|
||||
|
||||
static void enable_oled(struct asus_oled_dev *odev, uint8_t enabl)
|
||||
{
|
||||
int a;
|
||||
int retval;
|
||||
int act_len;
|
||||
struct asus_oled_packet * packet;
|
||||
struct asus_oled_packet *packet;
|
||||
|
||||
packet = kzalloc(sizeof(struct asus_oled_packet), GFP_KERNEL);
|
||||
|
||||
@@ -158,7 +165,7 @@ static void enable_oled(struct asus_oled_dev *odev, uint8_t enabl)
|
||||
return;
|
||||
}
|
||||
|
||||
SETUP_PACKET_HEADER(packet, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00);
|
||||
setup_packet_header(packet, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00);
|
||||
|
||||
if (enabl)
|
||||
packet->bitmap[0] = 0xaf;
|
||||
@@ -182,29 +189,34 @@ static void enable_oled(struct asus_oled_dev *odev, uint8_t enabl)
|
||||
kfree(packet);
|
||||
}
|
||||
|
||||
static ssize_t set_enabled(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
|
||||
static ssize_t set_enabled(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct usb_interface *intf = to_usb_interface(dev);
|
||||
struct asus_oled_dev *odev = usb_get_intfdata(intf);
|
||||
int temp = simple_strtoul(buf, NULL, 10);
|
||||
int temp = strict_strtoul(buf, 10, NULL);
|
||||
|
||||
enable_oled(odev, temp);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t class_set_enabled(struct device *device, struct device_attribute *attr, const char *buf, size_t count)
|
||||
static ssize_t class_set_enabled(struct device *device,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct asus_oled_dev *odev = (struct asus_oled_dev *) dev_get_drvdata(device);
|
||||
struct asus_oled_dev *odev =
|
||||
(struct asus_oled_dev *) dev_get_drvdata(device);
|
||||
|
||||
int temp = simple_strtoul(buf, NULL, 10);
|
||||
int temp = strict_strtoul(buf, 10, NULL);
|
||||
|
||||
enable_oled(odev, temp);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t get_enabled(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
static ssize_t get_enabled(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct usb_interface *intf = to_usb_interface(dev);
|
||||
struct asus_oled_dev *odev = usb_get_intfdata(intf);
|
||||
@@ -212,15 +224,18 @@ static ssize_t get_enabled(struct device *dev, struct device_attribute *attr, ch
|
||||
return sprintf(buf, "%d\n", odev->enabled);
|
||||
}
|
||||
|
||||
static ssize_t class_get_enabled(struct device *device, struct device_attribute *attr, char *buf)
|
||||
static ssize_t class_get_enabled(struct device *device,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct asus_oled_dev *odev = (struct asus_oled_dev *) dev_get_drvdata(device);
|
||||
struct asus_oled_dev *odev =
|
||||
(struct asus_oled_dev *) dev_get_drvdata(device);
|
||||
|
||||
return sprintf(buf, "%d\n", odev->enabled);
|
||||
}
|
||||
|
||||
static void send_packets(struct usb_device *udev, struct asus_oled_packet *packet,
|
||||
char *buf, uint8_t p_type, size_t p_num)
|
||||
static void send_packets(struct usb_device *udev,
|
||||
struct asus_oled_packet *packet,
|
||||
char *buf, uint8_t p_type, size_t p_num)
|
||||
{
|
||||
size_t i;
|
||||
int act_len;
|
||||
@@ -229,65 +244,76 @@ static void send_packets(struct usb_device *udev, struct asus_oled_packet *packe
|
||||
int retval;
|
||||
|
||||
switch (p_type) {
|
||||
case ASUS_OLED_ROLL:
|
||||
SETUP_PACKET_HEADER(packet, 0x40, 0x80, p_num, i + 1, 0x00, 0x01, 0xff);
|
||||
case ASUS_OLED_ROLL:
|
||||
setup_packet_header(packet, 0x40, 0x80, p_num,
|
||||
i + 1, 0x00, 0x01, 0xff);
|
||||
break;
|
||||
case ASUS_OLED_STATIC:
|
||||
SETUP_PACKET_HEADER(packet, 0x10 + i, 0x80, 0x01, 0x01, 0x00, 0x01, 0x00);
|
||||
case ASUS_OLED_STATIC:
|
||||
setup_packet_header(packet, 0x10 + i, 0x80, 0x01,
|
||||
0x01, 0x00, 0x01, 0x00);
|
||||
break;
|
||||
case ASUS_OLED_FLASH:
|
||||
SETUP_PACKET_HEADER(packet, 0x10 + i, 0x80, 0x01, 0x01, 0x00, 0x00, 0xff);
|
||||
case ASUS_OLED_FLASH:
|
||||
setup_packet_header(packet, 0x10 + i, 0x80, 0x01,
|
||||
0x01, 0x00, 0x00, 0xff);
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(packet->bitmap, buf + (ASUS_OLED_PACKET_BUF_SIZE*i), ASUS_OLED_PACKET_BUF_SIZE);
|
||||
memcpy(packet->bitmap, buf + (ASUS_OLED_PACKET_BUF_SIZE*i),
|
||||
ASUS_OLED_PACKET_BUF_SIZE);
|
||||
|
||||
retval = usb_bulk_msg(udev,
|
||||
usb_sndctrlpipe(udev, 2),
|
||||
packet,
|
||||
sizeof(struct asus_oled_packet),
|
||||
&act_len,
|
||||
-1);
|
||||
retval = usb_bulk_msg(udev, usb_sndctrlpipe(udev, 2),
|
||||
packet, sizeof(struct asus_oled_packet),
|
||||
&act_len, -1);
|
||||
|
||||
if (retval)
|
||||
dev_dbg(&udev->dev, "retval = %d\n", retval);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
SETUP_PACKET_HEADER(packet, b1, b2, b3, b4, b5, b6, 0x00);
|
||||
setup_packet_header(packet, b1, b2, b3, b4, b5, b6, 0x00);
|
||||
memcpy(packet->bitmap, buf + offset, len);
|
||||
|
||||
retval = usb_bulk_msg(udev,
|
||||
usb_sndctrlpipe(udev, 2),
|
||||
packet,
|
||||
sizeof(struct asus_oled_packet),
|
||||
&act_len,
|
||||
-1);
|
||||
usb_sndctrlpipe(udev, 2),
|
||||
packet,
|
||||
sizeof(struct asus_oled_packet),
|
||||
&act_len,
|
||||
-1);
|
||||
|
||||
if (retval)
|
||||
dev_dbg(&udev->dev, "retval = %d\n", retval);
|
||||
}
|
||||
|
||||
|
||||
static void send_packets_g50(struct usb_device *udev, struct asus_oled_packet *packet, char *buf)
|
||||
static void send_packets_g50(struct usb_device *udev,
|
||||
struct asus_oled_packet *packet, char *buf)
|
||||
{
|
||||
send_packet(udev, packet, 0, 0x100, buf, 0x10, 0x00, 0x02, 0x01, 0x00, 0x01);
|
||||
send_packet(udev, packet, 0x100, 0x080, buf, 0x10, 0x00, 0x02, 0x02, 0x80, 0x00);
|
||||
send_packet(udev, packet, 0, 0x100, buf,
|
||||
0x10, 0x00, 0x02, 0x01, 0x00, 0x01);
|
||||
send_packet(udev, packet, 0x100, 0x080, buf,
|
||||
0x10, 0x00, 0x02, 0x02, 0x80, 0x00);
|
||||
|
||||
send_packet(udev, packet, 0x180, 0x100, buf, 0x11, 0x00, 0x03, 0x01, 0x00, 0x01);
|
||||
send_packet(udev, packet, 0x280, 0x100, buf, 0x11, 0x00, 0x03, 0x02, 0x00, 0x01);
|
||||
send_packet(udev, packet, 0x380, 0x080, buf, 0x11, 0x00, 0x03, 0x03, 0x80, 0x00);
|
||||
send_packet(udev, packet, 0x180, 0x100, buf,
|
||||
0x11, 0x00, 0x03, 0x01, 0x00, 0x01);
|
||||
send_packet(udev, packet, 0x280, 0x100, buf,
|
||||
0x11, 0x00, 0x03, 0x02, 0x00, 0x01);
|
||||
send_packet(udev, packet, 0x380, 0x080, buf,
|
||||
0x11, 0x00, 0x03, 0x03, 0x80, 0x00);
|
||||
}
|
||||
|
||||
|
||||
static void send_data(struct asus_oled_dev *odev)
|
||||
{
|
||||
size_t packet_num = odev->buf_size / ASUS_OLED_PACKET_BUF_SIZE;
|
||||
struct asus_oled_packet * packet;
|
||||
struct asus_oled_packet *packet;
|
||||
|
||||
packet = kzalloc(sizeof(struct asus_oled_packet), GFP_KERNEL);
|
||||
|
||||
@@ -297,20 +323,20 @@ static void send_data(struct asus_oled_dev *odev)
|
||||
}
|
||||
|
||||
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.
|
||||
/* When sending roll-mode data the display updated only
|
||||
first packet. I have no idea why, but when static picture
|
||||
is sent just before rolling picture everything works fine. */
|
||||
if (odev->pic_mode == ASUS_OLED_ROLL)
|
||||
send_packets(odev->udev, packet, odev->buf, ASUS_OLED_STATIC, 2);
|
||||
send_packets(odev->udev, packet, odev->buf,
|
||||
ASUS_OLED_STATIC, 2);
|
||||
|
||||
// Only ROLL mode can use more than 2 packets.
|
||||
/* Only ROLL mode can use more than 2 packets.*/
|
||||
if (odev->pic_mode != ASUS_OLED_ROLL && packet_num > 2)
|
||||
packet_num = 2;
|
||||
|
||||
send_packets(odev->udev, packet, odev->buf, odev->pic_mode, packet_num);
|
||||
}
|
||||
else
|
||||
if (odev->pack_mode == PACK_MODE_G50) {
|
||||
send_packets(odev->udev, packet, odev->buf,
|
||||
odev->pic_mode, packet_num);
|
||||
} else if (odev->pack_mode == PACK_MODE_G50) {
|
||||
send_packets_g50(odev->udev, packet, odev->buf);
|
||||
}
|
||||
|
||||
@@ -319,53 +345,55 @@ static void send_data(struct asus_oled_dev *odev)
|
||||
|
||||
static int append_values(struct asus_oled_dev *odev, uint8_t val, size_t count)
|
||||
{
|
||||
while (count-- > 0) {
|
||||
if (val) {
|
||||
size_t x = odev->buf_offs % odev->width;
|
||||
size_t y = odev->buf_offs / odev->width;
|
||||
size_t i;
|
||||
while (count-- > 0 && val) {
|
||||
size_t x = odev->buf_offs % odev->width;
|
||||
size_t y = odev->buf_offs / odev->width;
|
||||
size_t i;
|
||||
|
||||
x += odev->x_shift;
|
||||
y += odev->y_shift;
|
||||
x += odev->x_shift;
|
||||
y += odev->y_shift;
|
||||
|
||||
switch (odev->pack_mode)
|
||||
{
|
||||
case PACK_MODE_G1:
|
||||
// i = (x/128)*640 + 127 - x + (y/8)*128;
|
||||
// This one for 128 is the same, but might be better for different widths?
|
||||
i = (x/odev->dev_width)*640 + odev->dev_width - 1 - x + (y/8)*odev->dev_width;
|
||||
break;
|
||||
switch (odev->pack_mode) {
|
||||
case PACK_MODE_G1:
|
||||
/* i = (x/128)*640 + 127 - x + (y/8)*128;
|
||||
This one for 128 is the same, but might be better
|
||||
for different widths? */
|
||||
i = (x/odev->dev_width)*640 +
|
||||
odev->dev_width - 1 - x +
|
||||
(y/8)*odev->dev_width;
|
||||
break;
|
||||
|
||||
case PACK_MODE_G50:
|
||||
i = (odev->dev_width - 1 - x)/8 + y*odev->dev_width/8;
|
||||
break;
|
||||
case PACK_MODE_G50:
|
||||
i = (odev->dev_width - 1 - x)/8 + y*odev->dev_width/8;
|
||||
break;
|
||||
|
||||
default:
|
||||
i = 0;
|
||||
printk(ASUS_OLED_ERROR "Unknown OLED Pack Mode: %d!\n", odev->pack_mode);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
i = 0;
|
||||
printk(ASUS_OLED_ERROR "Unknown OLED Pack Mode: %d!\n",
|
||||
odev->pack_mode);
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= odev->buf_size) {
|
||||
printk(ASUS_OLED_ERROR "Buffer overflow! Report a bug in the driver: offs: %d >= %d i: %d (x: %d y: %d)\n",
|
||||
(int) odev->buf_offs, (int) odev->buf_size, (int) i, (int) x, (int) y);
|
||||
return -EIO;
|
||||
}
|
||||
if (i >= odev->buf_size) {
|
||||
printk(ASUS_OLED_ERROR "Buffer overflow! Report a bug:"
|
||||
"offs: %d >= %d i: %d (x: %d y: %d)\n",
|
||||
(int) odev->buf_offs, (int) odev->buf_size,
|
||||
(int) i, (int) x, (int) y);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
switch (odev->pack_mode)
|
||||
{
|
||||
case PACK_MODE_G1:
|
||||
odev->buf[i] &= ~(1<<(y%8));
|
||||
break;
|
||||
switch (odev->pack_mode) {
|
||||
case PACK_MODE_G1:
|
||||
odev->buf[i] &= ~(1<<(y%8));
|
||||
break;
|
||||
|
||||
case PACK_MODE_G50:
|
||||
odev->buf[i] &= ~(1<<(x%8));
|
||||
break;
|
||||
case PACK_MODE_G50:
|
||||
odev->buf[i] &= ~(1<<(x%8));
|
||||
break;
|
||||
|
||||
default:
|
||||
// cannot get here; stops gcc complaining
|
||||
;
|
||||
}
|
||||
default:
|
||||
/* cannot get here; stops gcc complaining*/
|
||||
;
|
||||
}
|
||||
|
||||
odev->last_val = val;
|
||||
@@ -375,7 +403,8 @@ static int append_values(struct asus_oled_dev *odev, uint8_t val, size_t count)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t odev_set_picture(struct asus_oled_dev *odev, const char *buf, size_t count)
|
||||
static ssize_t odev_set_picture(struct asus_oled_dev *odev,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
size_t offs = 0, max_offs;
|
||||
|
||||
@@ -383,32 +412,31 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, const char *buf, siz
|
||||
return 0;
|
||||
|
||||
if (tolower(buf[0]) == 'b') {
|
||||
// binary mode, set the entire memory
|
||||
/* binary mode, set the entire memory*/
|
||||
|
||||
size_t i;
|
||||
size_t i;
|
||||
|
||||
odev->buf_size = (odev->dev_width * ASUS_OLED_DISP_HEIGHT) / 8;
|
||||
odev->buf_size = (odev->dev_width * ASUS_OLED_DISP_HEIGHT) / 8;
|
||||
|
||||
if (odev->buf)
|
||||
kfree(odev->buf);
|
||||
odev->buf = kmalloc(odev->buf_size, GFP_KERNEL);
|
||||
kfree(odev->buf);
|
||||
odev->buf = kmalloc(odev->buf_size, GFP_KERNEL);
|
||||
|
||||
memset(odev->buf, 0xff, odev->buf_size);
|
||||
memset(odev->buf, 0xff, odev->buf_size);
|
||||
|
||||
for (i = 1; i < count && i <= 32 * 32; i++) {
|
||||
odev->buf[i-1] = buf[i];
|
||||
odev->buf_offs = i-1;
|
||||
}
|
||||
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);
|
||||
send_data(odev);
|
||||
|
||||
return count;
|
||||
return count;
|
||||
}
|
||||
|
||||
if (buf[0] == '<') {
|
||||
@@ -416,20 +444,21 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, const char *buf, siz
|
||||
size_t w = 0, h = 0;
|
||||
size_t w_mem, h_mem;
|
||||
|
||||
if (count < 10 || buf[2] != ':') {
|
||||
if (count < 10 || buf[2] != ':')
|
||||
goto error_header;
|
||||
}
|
||||
|
||||
|
||||
switch (tolower(buf[1])) {
|
||||
case ASUS_OLED_STATIC:
|
||||
case ASUS_OLED_ROLL:
|
||||
case ASUS_OLED_FLASH:
|
||||
odev->pic_mode = buf[1];
|
||||
break;
|
||||
default:
|
||||
printk(ASUS_OLED_ERROR "Wrong picture mode: '%c'.\n", buf[1]);
|
||||
return -EIO;
|
||||
break;
|
||||
case ASUS_OLED_STATIC:
|
||||
case ASUS_OLED_ROLL:
|
||||
case ASUS_OLED_FLASH:
|
||||
odev->pic_mode = buf[1];
|
||||
break;
|
||||
default:
|
||||
printk(ASUS_OLED_ERROR "Wrong picture mode: '%c'.\n",
|
||||
buf[1]);
|
||||
return -EIO;
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 3; i < count; ++i) {
|
||||
@@ -438,11 +467,11 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, const char *buf, siz
|
||||
|
||||
if (w > ASUS_OLED_MAX_WIDTH)
|
||||
goto error_width;
|
||||
}
|
||||
else if (tolower(buf[i]) == 'x')
|
||||
} else if (tolower(buf[i]) == 'x') {
|
||||
break;
|
||||
else
|
||||
} else {
|
||||
goto error_width;
|
||||
}
|
||||
}
|
||||
|
||||
for (++i; i < count; ++i) {
|
||||
@@ -451,11 +480,11 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, const char *buf, siz
|
||||
|
||||
if (h > ASUS_OLED_DISP_HEIGHT)
|
||||
goto error_height;
|
||||
}
|
||||
else if (tolower(buf[i]) == '>')
|
||||
} else if (tolower(buf[i]) == '>') {
|
||||
break;
|
||||
else
|
||||
} else {
|
||||
goto error_height;
|
||||
}
|
||||
}
|
||||
|
||||
if (w < 1 || w > ASUS_OLED_MAX_WIDTH)
|
||||
@@ -481,8 +510,7 @@ 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);
|
||||
kfree(odev->buf);
|
||||
odev->buf = kmalloc(odev->buf_size, GFP_KERNEL);
|
||||
|
||||
if (odev->buf == NULL) {
|
||||
@@ -503,8 +531,7 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, const char *buf, siz
|
||||
if (odev->pic_mode == ASUS_OLED_FLASH) {
|
||||
if (h < ASUS_OLED_DISP_HEIGHT/2)
|
||||
odev->y_shift = (ASUS_OLED_DISP_HEIGHT/2 - h)/2;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (h < ASUS_OLED_DISP_HEIGHT)
|
||||
odev->y_shift = (ASUS_OLED_DISP_HEIGHT - h)/2;
|
||||
}
|
||||
@@ -522,20 +549,21 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, const char *buf, siz
|
||||
ret = append_values(odev, 1, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
else if (buf[offs] == '0' || buf[offs] == ' ') {
|
||||
} else if (buf[offs] == '0' || buf[offs] == ' ') {
|
||||
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.
|
||||
} 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)
|
||||
ret = append_values(odev, odev->last_val,
|
||||
odev->width - (odev->buf_offs % odev->width));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
odev->width -
|
||||
(odev->buf_offs %
|
||||
odev->width));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
offs++;
|
||||
@@ -559,47 +587,52 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, const char *buf, siz
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static ssize_t set_picture(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
|
||||
static ssize_t set_picture(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct usb_interface *intf = to_usb_interface(dev);
|
||||
|
||||
return odev_set_picture(usb_get_intfdata(intf), buf, count);
|
||||
}
|
||||
|
||||
static ssize_t class_set_picture(struct device *device, struct device_attribute *attr, const char *buf, size_t count)
|
||||
static ssize_t class_set_picture(struct device *device,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
return odev_set_picture((struct asus_oled_dev *) dev_get_drvdata(device), buf, count);
|
||||
return odev_set_picture((struct asus_oled_dev *)
|
||||
dev_get_drvdata(device), buf, count);
|
||||
}
|
||||
|
||||
#define ASUS_OLED_DEVICE_ATTR(_file) dev_attr_asus_oled_##_file
|
||||
|
||||
static DEVICE_ATTR(asus_oled_enabled, S_IWUGO | S_IRUGO, get_enabled, set_enabled);
|
||||
static DEVICE_ATTR(asus_oled_enabled, S_IWUGO | S_IRUGO,
|
||||
get_enabled, set_enabled);
|
||||
static DEVICE_ATTR(asus_oled_picture, S_IWUGO , NULL, set_picture);
|
||||
|
||||
static DEVICE_ATTR(enabled, S_IWUGO | S_IRUGO, class_get_enabled, class_set_enabled);
|
||||
static DEVICE_ATTR(enabled, S_IWUGO | S_IRUGO,
|
||||
class_get_enabled, class_set_enabled);
|
||||
static DEVICE_ATTR(picture, S_IWUGO, NULL, class_set_picture);
|
||||
|
||||
static int asus_oled_probe(struct usb_interface *interface, const struct usb_device_id *id)
|
||||
static int asus_oled_probe(struct usb_interface *interface,
|
||||
const struct usb_device_id *id)
|
||||
{
|
||||
struct usb_device *udev = interface_to_usbdev(interface);
|
||||
struct asus_oled_dev *odev = NULL;
|
||||
int retval = -ENOMEM;
|
||||
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;
|
||||
enum oled_pack_mode pack_mode = PACK_MODE_LAST;
|
||||
const struct oled_dev_desc_str *dev_desc = oled_dev_desc_table;
|
||||
const char *desc = NULL;
|
||||
|
||||
if (!id) {
|
||||
// Even possible? Just to make sure...
|
||||
/* Even possible? Just to make sure...*/
|
||||
dev_err(&interface->dev, "No usb_device_id provided!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
for (; dev_desc->idVendor; dev_desc++)
|
||||
{
|
||||
for (; dev_desc->idVendor; dev_desc++) {
|
||||
if (dev_desc->idVendor == id->idVendor
|
||||
&& dev_desc->idProduct == id->idProduct)
|
||||
{
|
||||
&& dev_desc->idProduct == id->idProduct) {
|
||||
dev_width = dev_desc->devWidth;
|
||||
desc = dev_desc->devDesc;
|
||||
pack_mode = dev_desc->packMode;
|
||||
@@ -608,7 +641,8 @@ static int asus_oled_probe(struct usb_interface *interface, const struct usb_dev
|
||||
}
|
||||
|
||||
if (!desc || dev_width < 1 || pack_mode == PACK_MODE_LAST) {
|
||||
dev_err(&interface->dev, "Missing or incomplete device description!\n");
|
||||
dev_err(&interface->dev,
|
||||
"Missing or incomplete device description!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
@@ -636,16 +670,18 @@ static int asus_oled_probe(struct usb_interface *interface, const struct usb_dev
|
||||
|
||||
usb_set_intfdata(interface, odev);
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
NULL, "oled_%d", ++oled_num);
|
||||
|
||||
if (IS_ERR(odev->dev)) {
|
||||
retval = PTR_ERR(odev->dev);
|
||||
@@ -662,7 +698,9 @@ static int asus_oled_probe(struct usb_interface *interface, const struct usb_dev
|
||||
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);
|
||||
dev_info(&interface->dev,
|
||||
"Attached Asus OLED device: %s [width %u, pack_mode %d]\n",
|
||||
desc, odev->dev_width, odev->pack_mode);
|
||||
|
||||
if (start_off)
|
||||
enable_oled(odev, 0);
|
||||
@@ -703,8 +741,7 @@ static void asus_oled_disconnect(struct usb_interface *interface)
|
||||
|
||||
usb_put_dev(odev->udev);
|
||||
|
||||
if (odev->buf)
|
||||
kfree(odev->buf);
|
||||
kfree(odev->buf);
|
||||
|
||||
kfree(odev);
|
||||
|
||||
@@ -720,7 +757,8 @@ static struct usb_driver oled_driver = {
|
||||
|
||||
static ssize_t version_show(struct class *dev, char *buf)
|
||||
{
|
||||
return sprintf(buf, ASUS_OLED_UNDERSCORE_NAME " %s\n", ASUS_OLED_VERSION);
|
||||
return sprintf(buf, ASUS_OLED_UNDERSCORE_NAME " %s\n",
|
||||
ASUS_OLED_VERSION);
|
||||
}
|
||||
|
||||
static CLASS_ATTR(version, S_IRUGO, version_show, NULL);
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
config USB_ATMEL
|
||||
tristate "Atmel at76c503/at76c505/at76c505a USB cards"
|
||||
depends on WLAN_80211 && USB
|
||||
default N
|
||||
select FW_LOADER
|
||||
---help---
|
||||
Enable support for USB Wireless devices using Atmel at76c503,
|
||||
at76c505 or at76c505a chips.
|
||||
@@ -1 +0,0 @@
|
||||
obj-$(CONFIG_USB_ATMEL) += at76_usb.o
|
||||
@@ -1,7 +0,0 @@
|
||||
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.
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,706 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2002,2003 Oliver Kurth
|
||||
* (c) 2003,2004 Joerg Albert <joerg.albert@gmx.de>
|
||||
* (c) 2007 Guido Guenther <agx@sigxcpu.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 driver was based on information from the Sourceforge driver
|
||||
* released and maintained by Atmel:
|
||||
*
|
||||
* http://sourceforge.net/projects/atmelwlandriver/
|
||||
*
|
||||
* Although the code was completely re-written,
|
||||
* it would have been impossible without Atmel's decision to
|
||||
* release an Open Source driver (unfortunately the firmware was
|
||||
* kept binary only). Thanks for that decision to Atmel!
|
||||
*/
|
||||
|
||||
#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,
|
||||
BOARD_503_ISL3863 = 2,
|
||||
BOARD_503 = 3,
|
||||
BOARD_503_ACC = 4,
|
||||
BOARD_505 = 5,
|
||||
BOARD_505_2958 = 6,
|
||||
BOARD_505A = 7,
|
||||
BOARD_505AMX = 8
|
||||
};
|
||||
|
||||
/* our private ioctl's */
|
||||
/* preamble length (0 - long, 1 - short, 2 - auto) */
|
||||
#define AT76_SET_SHORT_PREAMBLE (SIOCIWFIRSTPRIV + 0)
|
||||
#define AT76_GET_SHORT_PREAMBLE (SIOCIWFIRSTPRIV + 1)
|
||||
/* which debug channels are enabled */
|
||||
#define AT76_SET_DEBUG (SIOCIWFIRSTPRIV + 2)
|
||||
#define AT76_GET_DEBUG (SIOCIWFIRSTPRIV + 3)
|
||||
/* power save mode (incl. the Atmel proprietary smart save mode) */
|
||||
#define AT76_SET_POWERSAVE_MODE (SIOCIWFIRSTPRIV + 4)
|
||||
#define AT76_GET_POWERSAVE_MODE (SIOCIWFIRSTPRIV + 5)
|
||||
/* min and max channel times for scan */
|
||||
#define AT76_SET_SCAN_TIMES (SIOCIWFIRSTPRIV + 6)
|
||||
#define AT76_GET_SCAN_TIMES (SIOCIWFIRSTPRIV + 7)
|
||||
/* scan mode (0 - active, 1 - passive) */
|
||||
#define AT76_SET_SCAN_MODE (SIOCIWFIRSTPRIV + 8)
|
||||
#define AT76_GET_SCAN_MODE (SIOCIWFIRSTPRIV + 9)
|
||||
|
||||
#define CMD_STATUS_IDLE 0x00
|
||||
#define CMD_STATUS_COMPLETE 0x01
|
||||
#define CMD_STATUS_UNKNOWN 0x02
|
||||
#define CMD_STATUS_INVALID_PARAMETER 0x03
|
||||
#define CMD_STATUS_FUNCTION_NOT_SUPPORTED 0x04
|
||||
#define CMD_STATUS_TIME_OUT 0x07
|
||||
#define CMD_STATUS_IN_PROGRESS 0x08
|
||||
#define CMD_STATUS_HOST_FAILURE 0xff
|
||||
#define CMD_STATUS_SCAN_FAILED 0xf0
|
||||
|
||||
/* answers to get op mode */
|
||||
#define OPMODE_NONE 0x00
|
||||
#define OPMODE_NORMAL_NIC_WITH_FLASH 0x01
|
||||
#define OPMODE_HW_CONFIG_MODE 0x02
|
||||
#define OPMODE_DFU_MODE_WITH_FLASH 0x03
|
||||
#define OPMODE_NORMAL_NIC_WITHOUT_FLASH 0x04
|
||||
|
||||
#define CMD_SET_MIB 0x01
|
||||
#define CMD_GET_MIB 0x02
|
||||
#define CMD_SCAN 0x03
|
||||
#define CMD_JOIN 0x04
|
||||
#define CMD_START_IBSS 0x05
|
||||
#define CMD_RADIO_ON 0x06
|
||||
#define CMD_RADIO_OFF 0x07
|
||||
#define CMD_STARTUP 0x0B
|
||||
|
||||
#define MIB_LOCAL 0x01
|
||||
#define MIB_MAC_ADDR 0x02
|
||||
#define MIB_MAC 0x03
|
||||
#define MIB_MAC_MGMT 0x05
|
||||
#define MIB_MAC_WEP 0x06
|
||||
#define MIB_PHY 0x07
|
||||
#define MIB_FW_VERSION 0x08
|
||||
#define MIB_MDOMAIN 0x09
|
||||
|
||||
#define ADHOC_MODE 1
|
||||
#define INFRASTRUCTURE_MODE 2
|
||||
|
||||
/* values for struct mib_local, field preamble_type */
|
||||
#define PREAMBLE_TYPE_LONG 0
|
||||
#define PREAMBLE_TYPE_SHORT 1
|
||||
#define PREAMBLE_TYPE_AUTO 2
|
||||
|
||||
/* values for tx_rate */
|
||||
#define TX_RATE_1MBIT 0
|
||||
#define TX_RATE_2MBIT 1
|
||||
#define TX_RATE_5_5MBIT 2
|
||||
#define TX_RATE_11MBIT 3
|
||||
#define TX_RATE_AUTO 4
|
||||
|
||||
/* power management modes */
|
||||
#define AT76_PM_OFF 1
|
||||
#define AT76_PM_ON 2
|
||||
#define AT76_PM_SMART 3
|
||||
|
||||
struct hwcfg_r505 {
|
||||
u8 cr39_values[14];
|
||||
u8 reserved1[14];
|
||||
u8 bb_cr[14];
|
||||
u8 pidvid[4];
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
u8 regulatory_domain;
|
||||
u8 reserved2[14];
|
||||
u8 cr15_values[14];
|
||||
u8 reserved3[3];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct hwcfg_rfmd {
|
||||
u8 cr20_values[14];
|
||||
u8 cr21_values[14];
|
||||
u8 bb_cr[14];
|
||||
u8 pidvid[4];
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
u8 regulatory_domain;
|
||||
u8 low_power_values[14];
|
||||
u8 normal_power_values[14];
|
||||
u8 reserved1[3];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct hwcfg_intersil {
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
u8 cr31_values[14];
|
||||
u8 cr58_values[14];
|
||||
u8 pidvid[4];
|
||||
u8 regulatory_domain;
|
||||
u8 reserved[1];
|
||||
} __attribute__((packed));
|
||||
|
||||
union at76_hwcfg {
|
||||
struct hwcfg_intersil i;
|
||||
struct hwcfg_rfmd r3;
|
||||
struct hwcfg_r505 r5;
|
||||
};
|
||||
|
||||
#define WEP_SMALL_KEY_LEN (40 / 8)
|
||||
#define WEP_LARGE_KEY_LEN (104 / 8)
|
||||
|
||||
struct at76_card_config {
|
||||
u8 exclude_unencrypted;
|
||||
u8 promiscuous_mode;
|
||||
u8 short_retry_limit;
|
||||
u8 encryption_type;
|
||||
__le16 rts_threshold;
|
||||
__le16 fragmentation_threshold; /* 256..2346 */
|
||||
u8 basic_rate_set[4];
|
||||
u8 auto_rate_fallback; /* 0,1 */
|
||||
u8 channel;
|
||||
u8 privacy_invoked;
|
||||
u8 wep_default_key_id; /* 0..3 */
|
||||
u8 current_ssid[32];
|
||||
u8 wep_default_key_value[4][WEP_KEY_LEN];
|
||||
u8 ssid_len;
|
||||
u8 short_preamble;
|
||||
__le16 beacon_period;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct at76_command {
|
||||
u8 cmd;
|
||||
u8 reserved;
|
||||
__le16 size;
|
||||
u8 data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Length of Atmel-specific Rx header before 802.11 frame */
|
||||
#define AT76_RX_HDRLEN offsetof(struct at76_rx_buffer, packet)
|
||||
|
||||
struct at76_rx_buffer {
|
||||
__le16 wlength;
|
||||
u8 rx_rate;
|
||||
u8 newbss;
|
||||
u8 fragmentation;
|
||||
u8 rssi;
|
||||
u8 link_quality;
|
||||
u8 noise_level;
|
||||
__le32 rx_time;
|
||||
u8 packet[IEEE80211_FRAME_LEN + IEEE80211_FCS_LEN];
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Length of Atmel-specific Tx header before 802.11 frame */
|
||||
#define AT76_TX_HDRLEN offsetof(struct at76_tx_buffer, packet)
|
||||
|
||||
struct at76_tx_buffer {
|
||||
__le16 wlength;
|
||||
u8 tx_rate;
|
||||
u8 padding;
|
||||
u8 reserved[4];
|
||||
u8 packet[IEEE80211_FRAME_LEN + IEEE80211_FCS_LEN];
|
||||
} __attribute__((packed));
|
||||
|
||||
/* defines for scan_type below */
|
||||
#define SCAN_TYPE_ACTIVE 0
|
||||
#define SCAN_TYPE_PASSIVE 1
|
||||
|
||||
struct at76_req_scan {
|
||||
u8 bssid[ETH_ALEN];
|
||||
u8 essid[32];
|
||||
u8 scan_type;
|
||||
u8 channel;
|
||||
__le16 probe_delay;
|
||||
__le16 min_channel_time;
|
||||
__le16 max_channel_time;
|
||||
u8 essid_size;
|
||||
u8 international_scan;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct at76_req_ibss {
|
||||
u8 bssid[ETH_ALEN];
|
||||
u8 essid[32];
|
||||
u8 bss_type;
|
||||
u8 channel;
|
||||
u8 essid_size;
|
||||
u8 reserved[3];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct at76_req_join {
|
||||
u8 bssid[ETH_ALEN];
|
||||
u8 essid[32];
|
||||
u8 bss_type;
|
||||
u8 channel;
|
||||
__le16 timeout;
|
||||
u8 essid_size;
|
||||
u8 reserved;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct set_mib_buffer {
|
||||
u8 type;
|
||||
u8 size;
|
||||
u8 index;
|
||||
u8 reserved;
|
||||
union {
|
||||
u8 byte;
|
||||
__le16 word;
|
||||
u8 addr[ETH_ALEN];
|
||||
} data;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct mib_local {
|
||||
u16 reserved0;
|
||||
u8 beacon_enable;
|
||||
u8 txautorate_fallback;
|
||||
u8 reserved1;
|
||||
u8 ssid_size;
|
||||
u8 promiscuous_mode;
|
||||
u16 reserved2;
|
||||
u8 preamble_type;
|
||||
u16 reserved3;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct mib_mac_addr {
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
u8 res[2]; /* ??? */
|
||||
u8 group_addr[4][ETH_ALEN];
|
||||
u8 group_addr_status[4];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct mib_mac {
|
||||
__le32 max_tx_msdu_lifetime;
|
||||
__le32 max_rx_lifetime;
|
||||
__le16 frag_threshold;
|
||||
__le16 rts_threshold;
|
||||
__le16 cwmin;
|
||||
__le16 cwmax;
|
||||
u8 short_retry_time;
|
||||
u8 long_retry_time;
|
||||
u8 scan_type; /* active or passive */
|
||||
u8 scan_channel;
|
||||
__le16 probe_delay; /* delay before ProbeReq in active scan, RO */
|
||||
__le16 min_channel_time;
|
||||
__le16 max_channel_time;
|
||||
__le16 listen_interval;
|
||||
u8 desired_ssid[32];
|
||||
u8 desired_bssid[ETH_ALEN];
|
||||
u8 desired_bsstype; /* ad-hoc or infrastructure */
|
||||
u8 reserved2;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct mib_mac_mgmt {
|
||||
__le16 beacon_period;
|
||||
__le16 CFP_max_duration;
|
||||
__le16 medium_occupancy_limit;
|
||||
__le16 station_id; /* assoc id */
|
||||
__le16 ATIM_window;
|
||||
u8 CFP_mode;
|
||||
u8 privacy_option_implemented;
|
||||
u8 DTIM_period;
|
||||
u8 CFP_period;
|
||||
u8 current_bssid[ETH_ALEN];
|
||||
u8 current_essid[32];
|
||||
u8 current_bss_type;
|
||||
u8 power_mgmt_mode;
|
||||
/* rfmd and 505 */
|
||||
u8 ibss_change;
|
||||
u8 res;
|
||||
u8 multi_domain_capability_implemented;
|
||||
u8 multi_domain_capability_enabled;
|
||||
u8 country_string[3];
|
||||
u8 reserved[3];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct mib_mac_wep {
|
||||
u8 privacy_invoked; /* 0 disable encr., 1 enable encr */
|
||||
u8 wep_default_key_id;
|
||||
u8 wep_key_mapping_len;
|
||||
u8 exclude_unencrypted;
|
||||
__le32 wep_icv_error_count;
|
||||
__le32 wep_excluded_count;
|
||||
u8 wep_default_keyvalue[WEP_KEYS][WEP_KEY_LEN];
|
||||
u8 encryption_level; /* 1 for 40bit, 2 for 104bit encryption */
|
||||
} __attribute__((packed));
|
||||
|
||||
struct mib_phy {
|
||||
__le32 ed_threshold;
|
||||
|
||||
__le16 slot_time;
|
||||
__le16 sifs_time;
|
||||
__le16 preamble_length;
|
||||
__le16 plcp_header_length;
|
||||
__le16 mpdu_max_length;
|
||||
__le16 cca_mode_supported;
|
||||
|
||||
u8 operation_rate_set[4];
|
||||
u8 channel_id;
|
||||
u8 current_cca_mode;
|
||||
u8 phy_type;
|
||||
u8 current_reg_domain;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct mib_fw_version {
|
||||
u8 major;
|
||||
u8 minor;
|
||||
u8 patch;
|
||||
u8 build;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct mib_mdomain {
|
||||
u8 tx_powerlevel[14];
|
||||
u8 channel_list[14]; /* 0 for invalid channels */
|
||||
} __attribute__((packed));
|
||||
|
||||
struct at76_fw_header {
|
||||
__le32 crc; /* CRC32 of the whole image */
|
||||
__le32 board_type; /* firmware compatibility code */
|
||||
u8 build; /* firmware build number */
|
||||
u8 patch; /* firmware patch level */
|
||||
u8 minor; /* firmware minor version */
|
||||
u8 major; /* firmware major version */
|
||||
__le32 str_offset; /* offset of the copyright string */
|
||||
__le32 int_fw_offset; /* internal firmware image offset */
|
||||
__le32 int_fw_len; /* internal firmware image length */
|
||||
__le32 ext_fw_offset; /* external firmware image offset */
|
||||
__le32 ext_fw_len; /* external firmware image length */
|
||||
} __attribute__((packed));
|
||||
|
||||
enum mac_state {
|
||||
MAC_INIT,
|
||||
MAC_SCANNING,
|
||||
MAC_AUTH,
|
||||
MAC_ASSOC,
|
||||
MAC_JOINING,
|
||||
MAC_CONNECTED,
|
||||
MAC_OWN_IBSS
|
||||
};
|
||||
|
||||
/* a description of a regulatory domain and the allowed channels */
|
||||
struct reg_domain {
|
||||
u16 code;
|
||||
char const *name;
|
||||
u32 channel_map; /* if bit N is set, channel (N+1) is allowed */
|
||||
};
|
||||
|
||||
/* how long do we keep a (I)BSS in the bss_list in jiffies
|
||||
this should be long enough for the user to retrieve the table
|
||||
(by iwlist ?) after the device started, because all entries from
|
||||
other channels than the one the device locks on get removed, too */
|
||||
#define BSS_LIST_TIMEOUT (120 * HZ)
|
||||
/* struct to store BSS info found during scan */
|
||||
#define BSS_LIST_MAX_RATE_LEN 32 /* 32 rates should be enough ... */
|
||||
|
||||
struct bss_info {
|
||||
struct list_head list;
|
||||
|
||||
u8 bssid[ETH_ALEN]; /* bssid */
|
||||
u8 ssid[IW_ESSID_MAX_SIZE]; /* essid */
|
||||
u8 ssid_len; /* length of ssid above */
|
||||
u8 channel;
|
||||
u16 capa; /* BSS capabilities */
|
||||
u16 beacon_interval; /* beacon interval, Kus (1024 microseconds) */
|
||||
u8 rates[BSS_LIST_MAX_RATE_LEN]; /* supported rates in units of
|
||||
500 kbps, ORed with 0x80 for
|
||||
basic rates */
|
||||
u8 rates_len;
|
||||
|
||||
/* quality of received beacon */
|
||||
u8 rssi;
|
||||
u8 link_qual;
|
||||
u8 noise_level;
|
||||
|
||||
unsigned long last_rx; /* time (jiffies) of last beacon received */
|
||||
};
|
||||
|
||||
/* a rx data buffer to collect rx fragments */
|
||||
struct rx_data_buf {
|
||||
u8 sender[ETH_ALEN]; /* sender address */
|
||||
u16 seqnr; /* sequence number */
|
||||
u16 fragnr; /* last fragment received */
|
||||
unsigned long last_rx; /* jiffies of last rx */
|
||||
struct sk_buff *skb; /* == NULL if entry is free */
|
||||
};
|
||||
|
||||
#define NR_RX_DATA_BUF 8
|
||||
|
||||
/* Data for one loaded firmware file */
|
||||
struct fwentry {
|
||||
const char *const fwname;
|
||||
const struct firmware *fw;
|
||||
int extfw_size;
|
||||
int intfw_size;
|
||||
/* pointer to loaded firmware, no need to free */
|
||||
u8 *extfw; /* external firmware, extfw_size bytes long */
|
||||
u8 *intfw; /* internal firmware, intfw_size bytes long */
|
||||
enum board_type board_type; /* board type */
|
||||
struct mib_fw_version fw_version;
|
||||
int loaded; /* Loaded and parsed successfully */
|
||||
};
|
||||
|
||||
struct at76_priv {
|
||||
struct usb_device *udev; /* USB device pointer */
|
||||
struct net_device *netdev; /* net device pointer */
|
||||
struct net_device_stats stats; /* net device stats */
|
||||
struct iw_statistics wstats; /* wireless stats */
|
||||
|
||||
struct sk_buff *rx_skb; /* skbuff for receiving data */
|
||||
void *bulk_out_buffer; /* buffer for sending data */
|
||||
|
||||
struct urb *tx_urb; /* URB for sending data */
|
||||
struct urb *rx_urb; /* URB for receiving data */
|
||||
|
||||
unsigned int tx_pipe; /* bulk out pipe */
|
||||
unsigned int rx_pipe; /* bulk in pipe */
|
||||
|
||||
struct mutex mtx; /* locks this structure */
|
||||
|
||||
/* work queues */
|
||||
struct work_struct work_assoc_done;
|
||||
struct work_struct work_join;
|
||||
struct work_struct work_new_bss;
|
||||
struct work_struct work_start_scan;
|
||||
struct work_struct work_set_promisc;
|
||||
struct work_struct work_submit_rx;
|
||||
struct delayed_work dwork_restart;
|
||||
struct delayed_work dwork_get_scan;
|
||||
struct delayed_work dwork_beacon;
|
||||
struct delayed_work dwork_auth;
|
||||
struct delayed_work dwork_assoc;
|
||||
|
||||
struct tasklet_struct rx_tasklet;
|
||||
|
||||
/* the WEP stuff */
|
||||
int wep_enabled; /* 1 if WEP is enabled */
|
||||
int wep_key_id; /* key id to be used */
|
||||
u8 wep_keys[WEP_KEYS][WEP_KEY_LEN]; /* the four WEP keys,
|
||||
5 or 13 bytes are used */
|
||||
u8 wep_keys_len[WEP_KEYS]; /* the length of the above keys */
|
||||
|
||||
int channel;
|
||||
int iw_mode;
|
||||
u8 bssid[ETH_ALEN];
|
||||
u8 essid[IW_ESSID_MAX_SIZE];
|
||||
int essid_size;
|
||||
int radio_on;
|
||||
int promisc;
|
||||
|
||||
int preamble_type; /* 0 - long, 1 - short, 2 - auto */
|
||||
int auth_mode; /* authentication type: 0 open, 1 shared key */
|
||||
int txrate; /* 0,1,2,3 = 1,2,5.5,11 Mbps, 4 is auto */
|
||||
int frag_threshold; /* threshold for fragmentation of tx packets */
|
||||
int rts_threshold; /* threshold for RTS mechanism */
|
||||
int short_retry_limit;
|
||||
|
||||
int scan_min_time; /* scan min channel time */
|
||||
int scan_max_time; /* scan max channel time */
|
||||
int scan_mode; /* SCAN_TYPE_ACTIVE, SCAN_TYPE_PASSIVE */
|
||||
int scan_need_any; /* if set, need to scan for any ESSID */
|
||||
|
||||
/* the list we got from scanning */
|
||||
spinlock_t bss_list_spinlock; /* protects bss_list operations */
|
||||
struct list_head bss_list; /* list of BSS we got beacons from */
|
||||
struct timer_list bss_list_timer; /* timer to purge old entries
|
||||
from bss_list */
|
||||
struct bss_info *curr_bss; /* current BSS */
|
||||
u16 assoc_id; /* current association ID, if associated */
|
||||
|
||||
u8 wanted_bssid[ETH_ALEN];
|
||||
int wanted_bssid_valid; /* != 0 if wanted_bssid is to be used */
|
||||
|
||||
/* some data for infrastructure mode only */
|
||||
spinlock_t mgmt_spinlock; /* this spinlock protects access to
|
||||
next_mgmt_bulk */
|
||||
|
||||
struct at76_tx_buffer *next_mgmt_bulk; /* pending management msg to
|
||||
send via bulk out */
|
||||
enum mac_state mac_state;
|
||||
enum {
|
||||
SCAN_IDLE,
|
||||
SCAN_IN_PROGRESS,
|
||||
SCAN_COMPLETED
|
||||
} scan_state;
|
||||
time_t last_scan;
|
||||
|
||||
int retries; /* remaining retries in case of timeout when
|
||||
* sending AuthReq or AssocReq */
|
||||
u8 pm_mode; /* power management mode */
|
||||
u32 pm_period; /* power management period in microseconds */
|
||||
|
||||
struct reg_domain const *domain; /* reg domain description */
|
||||
|
||||
/* iwspy support */
|
||||
spinlock_t spy_spinlock;
|
||||
struct iw_spy_data spy_data;
|
||||
|
||||
struct iw_public_data wireless_data;
|
||||
|
||||
/* These fields contain HW config provided by the device (not all of
|
||||
* these fields are used by all board types) */
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
u8 regulatory_domain;
|
||||
|
||||
struct at76_card_config card_config;
|
||||
|
||||
/* store rx fragments until complete */
|
||||
struct rx_data_buf rx_data[NR_RX_DATA_BUF];
|
||||
|
||||
enum board_type board_type;
|
||||
struct mib_fw_version fw_version;
|
||||
|
||||
unsigned int device_unplugged:1;
|
||||
unsigned int netdev_registered:1;
|
||||
struct set_mib_buffer mib_buf; /* global buffer for set_mib calls */
|
||||
|
||||
/* beacon counting */
|
||||
int beacon_period; /* period of mgmt beacons, Kus */
|
||||
int beacons_received;
|
||||
unsigned long beacons_last_qual; /* time we restarted counting
|
||||
beacons */
|
||||
};
|
||||
|
||||
struct at76_rx_radiotap {
|
||||
struct ieee80211_radiotap_header rt_hdr;
|
||||
__le64 rt_tsft;
|
||||
u8 rt_flags;
|
||||
u8 rt_rate;
|
||||
s8 rt_signal;
|
||||
s8 rt_noise;
|
||||
};
|
||||
|
||||
#define AT76_RX_RADIOTAP_PRESENT \
|
||||
((1 << IEEE80211_RADIOTAP_TSFT) | \
|
||||
(1 << IEEE80211_RADIOTAP_FLAGS) | \
|
||||
(1 << IEEE80211_RADIOTAP_RATE) | \
|
||||
(1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | \
|
||||
(1 << IEEE80211_RADIOTAP_DB_ANTNOISE))
|
||||
|
||||
#define BEACON_MAX_DATA_LENGTH 1500
|
||||
|
||||
/* the maximum size of an AssocReq packet */
|
||||
#define ASSOCREQ_MAX_SIZE \
|
||||
(AT76_TX_HDRLEN + sizeof(struct ieee80211_assoc_request) + \
|
||||
1 + 1 + IW_ESSID_MAX_SIZE + 1 + 1 + 4)
|
||||
|
||||
/* for shared secret auth, add the challenge text size */
|
||||
#define AUTH_FRAME_SIZE (AT76_TX_HDRLEN + sizeof(struct ieee80211_auth))
|
||||
|
||||
/* Maximal number of AuthReq retries */
|
||||
#define AUTH_RETRIES 3
|
||||
|
||||
/* Maximal number of AssocReq retries */
|
||||
#define ASSOC_RETRIES 3
|
||||
|
||||
/* Beacon timeout in managed mode when we are connected */
|
||||
#define BEACON_TIMEOUT (10 * HZ)
|
||||
|
||||
/* Timeout for authentication response */
|
||||
#define AUTH_TIMEOUT (1 * HZ)
|
||||
|
||||
/* Timeout for association response */
|
||||
#define ASSOC_TIMEOUT (1 * HZ)
|
||||
|
||||
/* Polling interval when scan is running */
|
||||
#define SCAN_POLL_INTERVAL (HZ / 4)
|
||||
|
||||
/* Command completion timeout */
|
||||
#define CMD_COMPLETION_TIMEOUT (5 * HZ)
|
||||
|
||||
#define DEF_RTS_THRESHOLD 1536
|
||||
#define DEF_FRAG_THRESHOLD 1536
|
||||
#define DEF_SHORT_RETRY_LIMIT 8
|
||||
#define DEF_CHANNEL 10
|
||||
#define DEF_SCAN_MIN_TIME 10
|
||||
#define DEF_SCAN_MAX_TIME 120
|
||||
|
||||
#define MAX_RTS_THRESHOLD (MAX_FRAG_THRESHOLD + 1)
|
||||
|
||||
/* the max padding size for tx in bytes (see calc_padding) */
|
||||
#define MAX_PADDING_SIZE 53
|
||||
|
||||
#endif /* _AT76_USB_H */
|
||||
@@ -632,18 +632,15 @@ static void transfer_complete(struct b3dfg_dev *fgdev)
|
||||
fgdev->cur_dma_frame_addr = 0;
|
||||
|
||||
buf = list_entry(fgdev->buffer_queue.next, struct b3dfg_buffer, list);
|
||||
if (buf) {
|
||||
dev_dbg(dev, "handle frame completion\n");
|
||||
if (fgdev->cur_dma_frame_idx == B3DFG_FRAMES_PER_BUFFER - 1) {
|
||||
|
||||
/* last frame of that triplet completed */
|
||||
dev_dbg(dev, "triplet completed\n");
|
||||
buf->state = B3DFG_BUFFER_POPULATED;
|
||||
list_del_init(&buf->list);
|
||||
wake_up_interruptible(&fgdev->buffer_waitqueue);
|
||||
}
|
||||
} else {
|
||||
dev_err(dev, "got frame but no buffer!\n");
|
||||
dev_dbg(dev, "handle frame completion\n");
|
||||
if (fgdev->cur_dma_frame_idx == B3DFG_FRAMES_PER_BUFFER - 1) {
|
||||
|
||||
/* last frame of that triplet completed */
|
||||
dev_dbg(dev, "triplet completed\n");
|
||||
buf->state = B3DFG_BUFFER_POPULATED;
|
||||
list_del_init(&buf->list);
|
||||
wake_up_interruptible(&fgdev->buffer_waitqueue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -663,19 +660,15 @@ static bool setup_next_frame_transfer(struct b3dfg_dev *fgdev, int idx)
|
||||
dev_dbg(dev, "program DMA transfer for next frame: %d\n", idx);
|
||||
|
||||
buf = list_entry(fgdev->buffer_queue.next, struct b3dfg_buffer, list);
|
||||
if (buf) {
|
||||
if (idx == fgdev->cur_dma_frame_idx + 2) {
|
||||
if (setup_frame_transfer(fgdev, buf, idx - 1))
|
||||
dev_err(dev, "unable to map DMA buffer\n");
|
||||
need_ack = 0;
|
||||
} else {
|
||||
dev_err(dev, "frame mismatch, got %d, expected %d\n",
|
||||
idx, fgdev->cur_dma_frame_idx + 2);
|
||||
|
||||
/* FIXME: handle dropped triplets here */
|
||||
}
|
||||
if (idx == fgdev->cur_dma_frame_idx + 2) {
|
||||
if (setup_frame_transfer(fgdev, buf, idx - 1))
|
||||
dev_err(dev, "unable to map DMA buffer\n");
|
||||
need_ack = 0;
|
||||
} else {
|
||||
dev_err(dev, "cannot setup DMA, no buffer\n");
|
||||
dev_err(dev, "frame mismatch, got %d, expected %d\n",
|
||||
idx, fgdev->cur_dma_frame_idx + 2);
|
||||
|
||||
/* FIXME: handle dropped triplets here */
|
||||
}
|
||||
|
||||
return need_ack;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -51,7 +51,7 @@
|
||||
struct comedi32_chaninfo_struct {
|
||||
unsigned int subdev;
|
||||
compat_uptr_t maxdata_list; /* 32-bit 'unsigned int *' */
|
||||
compat_uptr_t flaglist; /* 32-bit 'unsigned int *' */
|
||||
compat_uptr_t flaglist; /* 32-bit 'unsigned int *' */
|
||||
compat_uptr_t rangelist; /* 32-bit 'unsigned int *' */
|
||||
unsigned int unused[4];
|
||||
};
|
||||
@@ -74,16 +74,16 @@ struct comedi32_cmd_struct {
|
||||
unsigned int scan_end_arg;
|
||||
unsigned int stop_src;
|
||||
unsigned int stop_arg;
|
||||
compat_uptr_t chanlist; /* 32-bit 'unsigned int *' */
|
||||
compat_uptr_t chanlist; /* 32-bit 'unsigned int *' */
|
||||
unsigned int chanlist_len;
|
||||
compat_uptr_t data; /* 32-bit 'short *' */
|
||||
compat_uptr_t data; /* 32-bit 'short *' */
|
||||
unsigned int data_len;
|
||||
};
|
||||
|
||||
struct comedi32_insn_struct {
|
||||
unsigned int insn;
|
||||
unsigned int n;
|
||||
compat_uptr_t data; /* 32-bit 'unsigned int *' */
|
||||
compat_uptr_t data; /* 32-bit 'unsigned int *' */
|
||||
unsigned int subdev;
|
||||
unsigned int chanspec;
|
||||
unsigned int unused[3];
|
||||
@@ -91,19 +91,19 @@ struct comedi32_insn_struct {
|
||||
|
||||
struct comedi32_insnlist_struct {
|
||||
unsigned int n_insns;
|
||||
compat_uptr_t insns; /* 32-bit 'struct comedi_insn *' */
|
||||
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)
|
||||
unsigned long arg)
|
||||
{
|
||||
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);
|
||||
int rc = (int)(*file->f_op->unlocked_ioctl) (file, cmd, arg);
|
||||
if (rc == -ENOIOCTLCMD)
|
||||
rc = -ENOTTY;
|
||||
return rc;
|
||||
@@ -112,8 +112,8 @@ static int translated_ioctl(struct file *file, unsigned int cmd,
|
||||
if (file->f_op->ioctl) {
|
||||
int rc;
|
||||
lock_kernel();
|
||||
rc = (*file->f_op->ioctl)(file->f_dentry->d_inode,
|
||||
file, cmd, arg);
|
||||
rc = (*file->f_op->ioctl) (file->f_dentry->d_inode,
|
||||
file, cmd, arg);
|
||||
unlock_kernel();
|
||||
return rc;
|
||||
}
|
||||
@@ -136,8 +136,7 @@ static int compat_chaninfo(struct file *file, unsigned long arg)
|
||||
|
||||
/* Copy chaninfo structure. Ignore unused members. */
|
||||
if (!access_ok(VERIFY_READ, chaninfo32, sizeof(*chaninfo32))
|
||||
|| !access_ok(VERIFY_WRITE, chaninfo,
|
||||
sizeof(*chaninfo))) {
|
||||
|| !access_ok(VERIFY_WRITE, chaninfo, sizeof(*chaninfo))) {
|
||||
return -EFAULT;
|
||||
}
|
||||
err = 0;
|
||||
@@ -171,8 +170,7 @@ static int compat_rangeinfo(struct file *file, unsigned long arg)
|
||||
|
||||
/* Copy rangeinfo structure. */
|
||||
if (!access_ok(VERIFY_READ, rangeinfo32, sizeof(*rangeinfo32))
|
||||
|| !access_ok(VERIFY_WRITE, rangeinfo,
|
||||
sizeof(*rangeinfo))) {
|
||||
|| !access_ok(VERIFY_WRITE, rangeinfo, sizeof(*rangeinfo))) {
|
||||
return -EFAULT;
|
||||
}
|
||||
err = 0;
|
||||
@@ -184,12 +182,12 @@ static int compat_rangeinfo(struct file *file, unsigned long arg)
|
||||
return -EFAULT;
|
||||
|
||||
return translated_ioctl(file, COMEDI_RANGEINFO,
|
||||
(unsigned long)rangeinfo);
|
||||
(unsigned long)rangeinfo);
|
||||
}
|
||||
|
||||
/* Copy 32-bit cmd structure to native cmd structure. */
|
||||
static int get_compat_cmd(struct comedi_cmd __user *cmd,
|
||||
struct comedi32_cmd_struct __user *cmd32)
|
||||
static int get_compat_cmd(struct comedi_cmd __user * cmd,
|
||||
struct comedi32_cmd_struct __user * cmd32)
|
||||
{
|
||||
int err;
|
||||
union {
|
||||
@@ -199,7 +197,7 @@ static int get_compat_cmd(struct comedi_cmd __user *cmd,
|
||||
|
||||
/* Copy cmd structure. */
|
||||
if (!access_ok(VERIFY_READ, cmd32, sizeof(*cmd32))
|
||||
|| !access_ok(VERIFY_WRITE, cmd, sizeof(*cmd))) {
|
||||
|| !access_ok(VERIFY_WRITE, cmd, sizeof(*cmd))) {
|
||||
return -EFAULT;
|
||||
}
|
||||
err = 0;
|
||||
@@ -239,7 +237,8 @@ static int get_compat_cmd(struct comedi_cmd __user *cmd,
|
||||
}
|
||||
|
||||
/* Copy native cmd structure to 32-bit cmd structure. */
|
||||
static int put_compat_cmd(struct comedi32_cmd_struct __user *cmd32, struct 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;
|
||||
@@ -249,7 +248,7 @@ static int put_compat_cmd(struct comedi32_cmd_struct __user *cmd32, struct comed
|
||||
/* (Could use ptr_to_compat() to set them, but that wasn't implemented
|
||||
* until kernel version 2.6.11.) */
|
||||
if (!access_ok(VERIFY_READ, cmd, sizeof(*cmd))
|
||||
|| !access_ok(VERIFY_WRITE, cmd32, sizeof(*cmd32))) {
|
||||
|| !access_ok(VERIFY_WRITE, cmd32, sizeof(*cmd32))) {
|
||||
return -EFAULT;
|
||||
}
|
||||
err = 0;
|
||||
@@ -329,8 +328,8 @@ static int compat_cmdtest(struct file *file, unsigned long arg)
|
||||
}
|
||||
|
||||
/* Copy 32-bit insn structure to native insn structure. */
|
||||
static int get_compat_insn(struct comedi_insn __user *insn,
|
||||
struct comedi32_insn_struct __user *insn32)
|
||||
static int get_compat_insn(struct comedi_insn __user * insn,
|
||||
struct comedi32_insn_struct __user * insn32)
|
||||
{
|
||||
int err;
|
||||
union {
|
||||
@@ -341,7 +340,7 @@ static int get_compat_insn(struct 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);
|
||||
@@ -385,7 +384,7 @@ static int compat_insnlist(struct file *file, unsigned long arg)
|
||||
|
||||
/* Allocate user memory to copy insnlist and insns into. */
|
||||
s = compat_alloc_user_space(offsetof(struct combined_insnlist,
|
||||
insn[n_insns]));
|
||||
insn[n_insns]));
|
||||
|
||||
/* Set native insnlist structure. */
|
||||
if (!access_ok(VERIFY_WRITE, &s->insnlist, sizeof(s->insnlist))) {
|
||||
@@ -404,7 +403,7 @@ static int compat_insnlist(struct file *file, unsigned long arg)
|
||||
}
|
||||
|
||||
return translated_ioctl(file, COMEDI_INSNLIST,
|
||||
(unsigned long)&s->insnlist);
|
||||
(unsigned long)&s->insnlist);
|
||||
}
|
||||
|
||||
/* Handle 32-bit COMEDI_INSN ioctl. */
|
||||
@@ -427,7 +426,7 @@ static int compat_insn(struct file *file, unsigned long arg)
|
||||
/* Process untranslated ioctl. */
|
||||
/* Returns -ENOIOCTLCMD for unrecognised ioctl codes. */
|
||||
static inline int raw_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
unsigned long arg)
|
||||
{
|
||||
int rc;
|
||||
|
||||
@@ -477,8 +476,7 @@ static inline int raw_ioctl(struct file *file, unsigned int cmd,
|
||||
|
||||
/* compat_ioctl file operation. */
|
||||
/* Returns -ENOIOCTLCMD for unrecognised ioctl codes. */
|
||||
long comedi_compat_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
long comedi_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
return raw_ioctl(file, cmd, arg);
|
||||
}
|
||||
@@ -497,7 +495,7 @@ long comedi_compat_ioctl(struct file *file, unsigned int cmd,
|
||||
|
||||
/* Handler for all 32-bit ioctl codes registered by this driver. */
|
||||
static int mapped_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg,
|
||||
struct file *file)
|
||||
struct file *file)
|
||||
{
|
||||
int rc;
|
||||
|
||||
@@ -515,27 +513,27 @@ static int mapped_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg,
|
||||
|
||||
struct ioctl32_map {
|
||||
unsigned int cmd;
|
||||
int (*handler)(unsigned int, unsigned int, unsigned long,
|
||||
int (*handler) (unsigned int, unsigned int, unsigned long,
|
||||
struct file *);
|
||||
int registered;
|
||||
};
|
||||
|
||||
static struct ioctl32_map comedi_ioctl32_map[] = {
|
||||
{ COMEDI_DEVCONFIG, mapped_ioctl, 0 },
|
||||
{ COMEDI_DEVINFO, mapped_ioctl, 0 },
|
||||
{ COMEDI_SUBDINFO, mapped_ioctl, 0 },
|
||||
{ COMEDI_BUFCONFIG, mapped_ioctl, 0 },
|
||||
{ COMEDI_BUFINFO, mapped_ioctl, 0 },
|
||||
{ COMEDI_LOCK, mapped_ioctl, 0 },
|
||||
{ COMEDI_UNLOCK, mapped_ioctl, 0 },
|
||||
{ COMEDI_CANCEL, mapped_ioctl, 0 },
|
||||
{ COMEDI_POLL, mapped_ioctl, 0 },
|
||||
{ COMEDI32_CHANINFO, mapped_ioctl, 0 },
|
||||
{ COMEDI32_RANGEINFO, mapped_ioctl, 0 },
|
||||
{ COMEDI32_CMD, mapped_ioctl, 0 },
|
||||
{ COMEDI32_CMDTEST, mapped_ioctl, 0 },
|
||||
{ COMEDI32_INSNLIST, mapped_ioctl, 0 },
|
||||
{ COMEDI32_INSN, mapped_ioctl, 0 },
|
||||
{COMEDI_DEVCONFIG, mapped_ioctl, 0},
|
||||
{COMEDI_DEVINFO, mapped_ioctl, 0},
|
||||
{COMEDI_SUBDINFO, mapped_ioctl, 0},
|
||||
{COMEDI_BUFCONFIG, mapped_ioctl, 0},
|
||||
{COMEDI_BUFINFO, mapped_ioctl, 0},
|
||||
{COMEDI_LOCK, mapped_ioctl, 0},
|
||||
{COMEDI_UNLOCK, mapped_ioctl, 0},
|
||||
{COMEDI_CANCEL, mapped_ioctl, 0},
|
||||
{COMEDI_POLL, mapped_ioctl, 0},
|
||||
{COMEDI32_CHANINFO, mapped_ioctl, 0},
|
||||
{COMEDI32_RANGEINFO, mapped_ioctl, 0},
|
||||
{COMEDI32_CMD, mapped_ioctl, 0},
|
||||
{COMEDI32_CMDTEST, mapped_ioctl, 0},
|
||||
{COMEDI32_INSNLIST, mapped_ioctl, 0},
|
||||
{COMEDI32_INSN, mapped_ioctl, 0},
|
||||
};
|
||||
|
||||
#define NUM_IOCTL32_MAPS ARRAY_SIZE(comedi_ioctl32_map)
|
||||
@@ -547,13 +545,13 @@ void comedi_register_ioctl32(void)
|
||||
|
||||
for (n = 0; n < NUM_IOCTL32_MAPS; n++) {
|
||||
rc = register_ioctl32_conversion(comedi_ioctl32_map[n].cmd,
|
||||
comedi_ioctl32_map[n].handler);
|
||||
comedi_ioctl32_map[n].handler);
|
||||
if (rc) {
|
||||
printk(KERN_WARNING
|
||||
"comedi: failed to register 32-bit "
|
||||
"compatible ioctl handler for 0x%X - "
|
||||
"expect bad things to happen!\n",
|
||||
comedi_ioctl32_map[n].cmd);
|
||||
"comedi: failed to register 32-bit "
|
||||
"compatible ioctl handler for 0x%X - "
|
||||
"expect bad things to happen!\n",
|
||||
comedi_ioctl32_map[n].cmd);
|
||||
}
|
||||
comedi_ioctl32_map[n].registered = !rc;
|
||||
}
|
||||
@@ -566,15 +564,16 @@ void comedi_unregister_ioctl32(void)
|
||||
|
||||
for (n = 0; n < NUM_IOCTL32_MAPS; n++) {
|
||||
if (comedi_ioctl32_map[n].registered) {
|
||||
rc = unregister_ioctl32_conversion(
|
||||
comedi_ioctl32_map[n].cmd,
|
||||
comedi_ioctl32_map[n].handler);
|
||||
rc = unregister_ioctl32_conversion(comedi_ioctl32_map
|
||||
[n].cmd,
|
||||
comedi_ioctl32_map
|
||||
[n].handler);
|
||||
if (rc) {
|
||||
printk(KERN_ERR
|
||||
"comedi: failed to unregister 32-bit "
|
||||
"compatible ioctl handler for 0x%X - "
|
||||
"expect kernel Oops!\n",
|
||||
comedi_ioctl32_map[n].cmd);
|
||||
"comedi: failed to unregister 32-bit "
|
||||
"compatible ioctl handler for 0x%X - "
|
||||
"expect kernel Oops!\n",
|
||||
comedi_ioctl32_map[n].cmd);
|
||||
} else {
|
||||
comedi_ioctl32_map[n].registered = 0;
|
||||
}
|
||||
@@ -582,6 +581,6 @@ void comedi_unregister_ioctl32(void)
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAVE_COMPAT_IOCTL */
|
||||
#endif /* HAVE_COMPAT_IOCTL */
|
||||
|
||||
#endif /* CONFIG_COMPAT */
|
||||
#endif /* CONFIG_COMPAT */
|
||||
|
||||
@@ -28,14 +28,14 @@
|
||||
#define _COMEDI_COMPAT32_H
|
||||
|
||||
#include <linux/compat.h>
|
||||
#include <linux/fs.h> /* For HAVE_COMPAT_IOCTL and HAVE_UNLOCKED_IOCTL */
|
||||
#include <linux/fs.h> /* For HAVE_COMPAT_IOCTL and HAVE_UNLOCKED_IOCTL */
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
|
||||
#ifdef HAVE_COMPAT_IOCTL
|
||||
|
||||
extern long comedi_compat_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long arg);
|
||||
unsigned long arg);
|
||||
#define comedi_register_ioctl32() do {} while (0)
|
||||
#define comedi_unregister_ioctl32() do {} while (0)
|
||||
|
||||
|
||||
@@ -68,26 +68,33 @@ 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];
|
||||
*comedi_file_info_table[COMEDI_NUM_MINORS];
|
||||
|
||||
static int do_devconfig_ioctl(struct comedi_device *dev, struct comedi_devconfig *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(struct comedi_device *dev, struct comedi_subdinfo *arg,
|
||||
void *file);
|
||||
static int do_chaninfo_ioctl(struct comedi_device *dev, struct comedi_chaninfo *arg);
|
||||
static int do_devinfo_ioctl(struct comedi_device *dev,
|
||||
struct comedi_devinfo *arg, struct file *file);
|
||||
static int do_subdinfo_ioctl(struct comedi_device *dev,
|
||||
struct comedi_subdinfo *arg, 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_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);
|
||||
static int do_poll_ioctl(struct comedi_device *dev, unsigned int subd,
|
||||
void *file);
|
||||
|
||||
extern void do_become_nonbusy(struct comedi_device *dev, struct 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);
|
||||
@@ -202,7 +209,8 @@ static int comedi_ioctl(struct inode *inode, struct file *file,
|
||||
writes:
|
||||
none
|
||||
*/
|
||||
static int do_devconfig_ioctl(struct comedi_device *dev, struct comedi_devconfig *arg)
|
||||
static int do_devconfig_ioctl(struct comedi_device *dev,
|
||||
struct comedi_devconfig *arg)
|
||||
{
|
||||
struct comedi_devconfig it;
|
||||
int ret;
|
||||
@@ -342,8 +350,8 @@ static int do_bufconfig_ioctl(struct comedi_device *dev, void *arg)
|
||||
devinfo structure
|
||||
|
||||
*/
|
||||
static int do_devinfo_ioctl(struct comedi_device *dev, struct comedi_devinfo *arg,
|
||||
struct file *file)
|
||||
static int do_devinfo_ioctl(struct comedi_device *dev,
|
||||
struct comedi_devinfo *arg, struct file *file)
|
||||
{
|
||||
struct comedi_devinfo devinfo;
|
||||
const unsigned minor = iminor(file->f_dentry->d_inode);
|
||||
@@ -392,14 +400,16 @@ static int do_devinfo_ioctl(struct comedi_device *dev, struct comedi_devinfo *ar
|
||||
array of subdevice info structures at arg
|
||||
|
||||
*/
|
||||
static int do_subdinfo_ioctl(struct comedi_device *dev, struct comedi_subdinfo *arg,
|
||||
void *file)
|
||||
static int do_subdinfo_ioctl(struct comedi_device *dev,
|
||||
struct comedi_subdinfo *arg, void *file)
|
||||
{
|
||||
int ret, i;
|
||||
struct comedi_subdinfo *tmp, *us;
|
||||
struct comedi_subdevice *s;
|
||||
|
||||
tmp = kcalloc(dev->n_subdevices, sizeof(struct comedi_subdinfo), GFP_KERNEL);
|
||||
tmp =
|
||||
kcalloc(dev->n_subdevices, sizeof(struct comedi_subdinfo),
|
||||
GFP_KERNEL);
|
||||
if (!tmp)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -472,7 +482,8 @@ static int do_subdinfo_ioctl(struct comedi_device *dev, struct comedi_subdinfo *
|
||||
arrays at elements of chaninfo structure
|
||||
|
||||
*/
|
||||
static int do_chaninfo_ioctl(struct comedi_device *dev, struct comedi_chaninfo *arg)
|
||||
static int do_chaninfo_ioctl(struct comedi_device *dev,
|
||||
struct comedi_chaninfo *arg)
|
||||
{
|
||||
struct comedi_subdevice *s;
|
||||
struct comedi_chaninfo it;
|
||||
@@ -514,7 +525,7 @@ static int do_chaninfo_ioctl(struct comedi_device *dev, struct comedi_chaninfo *
|
||||
}
|
||||
#if 0
|
||||
if (copy_to_user(it.rangelist, s->range_type_list,
|
||||
s->n_chan*sizeof(unsigned int)))
|
||||
s->n_chan * sizeof(unsigned int)))
|
||||
return -EFAULT;
|
||||
#endif
|
||||
}
|
||||
@@ -589,8 +600,8 @@ static int do_bufinfo_ioctl(struct comedi_device *dev, void *arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data,
|
||||
void *file);
|
||||
static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn,
|
||||
unsigned int *data, void *file);
|
||||
/*
|
||||
* COMEDI_INSNLIST
|
||||
* synchronous instructions
|
||||
@@ -626,7 +637,8 @@ static int do_insnlist_ioctl(struct comedi_device *dev, void *arg, void *file)
|
||||
goto error;
|
||||
}
|
||||
|
||||
insns = kmalloc(sizeof(struct 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;
|
||||
@@ -678,7 +690,8 @@ static int do_insnlist_ioctl(struct comedi_device *dev, void *arg, void *file)
|
||||
return i;
|
||||
}
|
||||
|
||||
static int check_insn_config_length(struct comedi_insn *insn, unsigned int *data)
|
||||
static int check_insn_config_length(struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
if (insn->n < 1)
|
||||
return -EINVAL;
|
||||
@@ -725,22 +738,22 @@ static int check_insn_config_length(struct comedi_insn *insn, unsigned int *data
|
||||
if (insn->n == 5)
|
||||
return 0;
|
||||
break;
|
||||
/* by default we allow the insn since we don't have checks for
|
||||
* all possible cases yet */
|
||||
/* by default we allow the insn since we don't have checks for
|
||||
* all possible cases yet */
|
||||
default:
|
||||
printk("comedi: no check for data length of config insn id "
|
||||
"%i is implemented.\n"
|
||||
" Add a check to %s in %s.\n"
|
||||
" Assuming n=%i is correct.\n", data[0], __func__,
|
||||
__FILE__, insn->n);
|
||||
"%i is implemented.\n"
|
||||
" Add a check to %s in %s.\n"
|
||||
" Assuming n=%i is correct.\n", data[0], __func__,
|
||||
__FILE__, insn->n);
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data,
|
||||
void *file)
|
||||
static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn,
|
||||
unsigned int *data, void *file)
|
||||
{
|
||||
struct comedi_subdevice *s;
|
||||
int ret = 0;
|
||||
@@ -920,7 +933,8 @@ static int do_insn_ioctl(struct 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(unsigned int))) {
|
||||
if (copy_from_user
|
||||
(data, insn.data, insn.n * sizeof(unsigned int))) {
|
||||
ret = -EFAULT;
|
||||
goto error;
|
||||
}
|
||||
@@ -929,7 +943,8 @@ static int do_insn_ioctl(struct 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(unsigned int))) {
|
||||
if (copy_to_user
|
||||
(insn.data, data, insn.n * sizeof(unsigned int))) {
|
||||
ret = -EFAULT;
|
||||
goto error;
|
||||
}
|
||||
@@ -1202,7 +1217,8 @@ static int do_cmdtest_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_lock_ioctl(struct comedi_device *dev, unsigned int arg,
|
||||
void *file)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned long flags;
|
||||
@@ -1246,7 +1262,8 @@ static int do_lock_ioctl(struct 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(struct comedi_device *dev, unsigned int arg, void *file)
|
||||
static int do_unlock_ioctl(struct comedi_device *dev, unsigned int arg,
|
||||
void *file)
|
||||
{
|
||||
struct comedi_subdevice *s;
|
||||
|
||||
@@ -1286,7 +1303,8 @@ static int do_unlock_ioctl(struct comedi_device *dev, unsigned int arg, void *fi
|
||||
nothing
|
||||
|
||||
*/
|
||||
static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg, void *file)
|
||||
static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg,
|
||||
void *file)
|
||||
{
|
||||
struct comedi_subdevice *s;
|
||||
|
||||
@@ -1322,7 +1340,8 @@ static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg, void *fi
|
||||
nothing
|
||||
|
||||
*/
|
||||
static int do_poll_ioctl(struct comedi_device *dev, unsigned int arg, void *file)
|
||||
static int do_poll_ioctl(struct comedi_device *dev, unsigned int arg,
|
||||
void *file)
|
||||
{
|
||||
struct comedi_subdevice *s;
|
||||
|
||||
@@ -1371,7 +1390,7 @@ void comedi_unmap(struct vm_area_struct *area)
|
||||
}
|
||||
|
||||
static struct vm_operations_struct comedi_vm_ops = {
|
||||
.close = comedi_unmap,
|
||||
.close = comedi_unmap,
|
||||
};
|
||||
|
||||
static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
|
||||
@@ -1428,10 +1447,10 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
|
||||
n_pages = size >> PAGE_SHIFT;
|
||||
for (i = 0; i < n_pages; ++i) {
|
||||
if (remap_pfn_range(vma, start,
|
||||
page_to_pfn(virt_to_page(async->
|
||||
buf_page_list[i].
|
||||
virt_addr)),
|
||||
PAGE_SIZE, PAGE_SHARED)) {
|
||||
page_to_pfn(virt_to_page
|
||||
(async->buf_page_list
|
||||
[i].virt_addr)), PAGE_SIZE,
|
||||
PAGE_SHARED)) {
|
||||
retval = -EAGAIN;
|
||||
goto done;
|
||||
}
|
||||
@@ -1449,7 +1468,7 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static unsigned int comedi_poll(struct file *file, poll_table *wait)
|
||||
static unsigned int comedi_poll(struct file *file, poll_table * wait)
|
||||
{
|
||||
unsigned int mask = 0;
|
||||
const unsigned minor = iminor(file->f_dentry->d_inode);
|
||||
@@ -1496,7 +1515,7 @@ 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)
|
||||
loff_t * offset)
|
||||
{
|
||||
struct comedi_subdevice *s;
|
||||
struct comedi_async *async;
|
||||
@@ -1598,7 +1617,7 @@ static ssize_t comedi_write(struct file *file, const char *buf, size_t nbytes,
|
||||
}
|
||||
|
||||
static ssize_t comedi_read(struct file *file, char *buf, size_t nbytes,
|
||||
loff_t *offset)
|
||||
loff_t * offset)
|
||||
{
|
||||
struct comedi_subdevice *s;
|
||||
struct comedi_async *async;
|
||||
@@ -1729,7 +1748,8 @@ static int comedi_open(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);
|
||||
struct comedi_device *dev = dev_file_info ? dev_file_info->device : NULL;
|
||||
struct comedi_device *dev =
|
||||
dev_file_info ? dev_file_info->device : NULL;
|
||||
|
||||
if (dev == NULL) {
|
||||
DPRINTK("invalid minor number\n");
|
||||
@@ -1846,22 +1866,22 @@ static int comedi_fasync(int fd, struct file *file, int on)
|
||||
}
|
||||
|
||||
const struct file_operations comedi_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.owner = THIS_MODULE,
|
||||
#ifdef HAVE_UNLOCKED_IOCTL
|
||||
.unlocked_ioctl = comedi_unlocked_ioctl,
|
||||
.unlocked_ioctl = comedi_unlocked_ioctl,
|
||||
#else
|
||||
.ioctl = comedi_ioctl,
|
||||
.ioctl = comedi_ioctl,
|
||||
#endif
|
||||
#ifdef HAVE_COMPAT_IOCTL
|
||||
.compat_ioctl = comedi_compat_ioctl,
|
||||
.compat_ioctl = comedi_compat_ioctl,
|
||||
#endif
|
||||
.open = comedi_open,
|
||||
.release = comedi_close,
|
||||
.read = comedi_read,
|
||||
.write = comedi_write,
|
||||
.mmap = comedi_mmap,
|
||||
.poll = comedi_poll,
|
||||
.fasync = comedi_fasync,
|
||||
.open = comedi_open,
|
||||
.release = comedi_close,
|
||||
.read = comedi_read,
|
||||
.write = comedi_write,
|
||||
.mmap = comedi_mmap,
|
||||
.poll = comedi_poll,
|
||||
.fasync = comedi_fasync,
|
||||
};
|
||||
|
||||
struct class *comedi_class;
|
||||
@@ -1952,7 +1972,6 @@ static void __exit comedi_cleanup(void)
|
||||
for (i = 0; i < COMEDI_NUM_MINORS; ++i)
|
||||
BUG_ON(comedi_file_info_table[i]);
|
||||
|
||||
|
||||
class_destroy(comedi_class);
|
||||
cdev_del(&comedi_cdev);
|
||||
unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0), COMEDI_NUM_MINORS);
|
||||
@@ -1981,8 +2000,9 @@ void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
if ((comedi_get_subdevice_runflags(s) & SRF_RUNNING) == 0)
|
||||
return;
|
||||
|
||||
if (s->async->
|
||||
events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW)) {
|
||||
if (s->
|
||||
async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR |
|
||||
COMEDI_CB_OVERFLOW)) {
|
||||
runflags_mask |= SRF_RUNNING;
|
||||
}
|
||||
/* remember if an error event has occured, so an error
|
||||
@@ -2000,12 +2020,10 @@ void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
if (comedi_get_subdevice_runflags(s) & SRF_USER) {
|
||||
wake_up_interruptible(&async->wait_head);
|
||||
if (s->subdev_flags & SDF_CMD_READ) {
|
||||
kill_fasync(&dev->async_queue, SIGIO,
|
||||
POLL_IN);
|
||||
kill_fasync(&dev->async_queue, SIGIO, POLL_IN);
|
||||
}
|
||||
if (s->subdev_flags & SDF_CMD_WRITE) {
|
||||
kill_fasync(&dev->async_queue, SIGIO,
|
||||
POLL_OUT);
|
||||
kill_fasync(&dev->async_queue, SIGIO, POLL_OUT);
|
||||
}
|
||||
} else {
|
||||
if (async->cb_func)
|
||||
@@ -2103,7 +2121,8 @@ int comedi_alloc_board_minor(struct device *hardware_device)
|
||||
comedi_device_cleanup(info->device);
|
||||
kfree(info->device);
|
||||
kfree(info);
|
||||
printk(KERN_ERR "comedi: error: ran out of minor numbers for board device files.\n");
|
||||
printk(KERN_ERR
|
||||
"comedi: error: ran out of minor numbers for board device files.\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
info->device->minor = i;
|
||||
@@ -2115,29 +2134,33 @@ int comedi_alloc_board_minor(struct device *hardware_device)
|
||||
dev_set_drvdata(csdev, info);
|
||||
retval = device_create_file(csdev, &dev_attr_max_read_buffer_kb);
|
||||
if (retval) {
|
||||
printk(KERN_ERR "comedi: failed to create sysfs attribute file \"%s\".\n",
|
||||
dev_attr_max_read_buffer_kb.attr.name);
|
||||
printk(KERN_ERR
|
||||
"comedi: failed to create sysfs attribute file \"%s\".\n",
|
||||
dev_attr_max_read_buffer_kb.attr.name);
|
||||
comedi_free_board_minor(i);
|
||||
return retval;
|
||||
}
|
||||
retval = device_create_file(csdev, &dev_attr_read_buffer_kb);
|
||||
if (retval) {
|
||||
printk(KERN_ERR "comedi: failed to create sysfs attribute file \"%s\".\n",
|
||||
dev_attr_read_buffer_kb.attr.name);
|
||||
printk(KERN_ERR
|
||||
"comedi: failed to create sysfs attribute file \"%s\".\n",
|
||||
dev_attr_read_buffer_kb.attr.name);
|
||||
comedi_free_board_minor(i);
|
||||
return retval;
|
||||
}
|
||||
retval = device_create_file(csdev, &dev_attr_max_write_buffer_kb);
|
||||
if (retval) {
|
||||
printk(KERN_ERR "comedi: failed to create sysfs attribute file \"%s\".\n",
|
||||
dev_attr_max_write_buffer_kb.attr.name);
|
||||
printk(KERN_ERR
|
||||
"comedi: failed to create sysfs attribute file \"%s\".\n",
|
||||
dev_attr_max_write_buffer_kb.attr.name);
|
||||
comedi_free_board_minor(i);
|
||||
return retval;
|
||||
}
|
||||
retval = device_create_file(csdev, &dev_attr_write_buffer_kb);
|
||||
if (retval) {
|
||||
printk(KERN_ERR "comedi: failed to create sysfs attribute file \"%s\".\n",
|
||||
dev_attr_write_buffer_kb.attr.name);
|
||||
printk(KERN_ERR
|
||||
"comedi: failed to create sysfs attribute file \"%s\".\n",
|
||||
dev_attr_write_buffer_kb.attr.name);
|
||||
comedi_free_board_minor(i);
|
||||
return retval;
|
||||
}
|
||||
@@ -2194,7 +2217,8 @@ int comedi_alloc_subdevice_minor(struct comedi_device *dev,
|
||||
spin_unlock_irqrestore(&comedi_file_info_table_lock, flags);
|
||||
if (i == COMEDI_NUM_MINORS) {
|
||||
kfree(info);
|
||||
printk(KERN_ERR "comedi: error: ran out of minor numbers for board device files.\n");
|
||||
printk(KERN_ERR
|
||||
"comedi: error: ran out of minor numbers for board device files.\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
s->minor = i;
|
||||
@@ -2207,29 +2231,33 @@ int comedi_alloc_subdevice_minor(struct comedi_device *dev,
|
||||
dev_set_drvdata(csdev, info);
|
||||
retval = device_create_file(csdev, &dev_attr_max_read_buffer_kb);
|
||||
if (retval) {
|
||||
printk(KERN_ERR "comedi: failed to create sysfs attribute file \"%s\".\n",
|
||||
dev_attr_max_read_buffer_kb.attr.name);
|
||||
printk(KERN_ERR
|
||||
"comedi: failed to create sysfs attribute file \"%s\".\n",
|
||||
dev_attr_max_read_buffer_kb.attr.name);
|
||||
comedi_free_subdevice_minor(s);
|
||||
return retval;
|
||||
}
|
||||
retval = device_create_file(csdev, &dev_attr_read_buffer_kb);
|
||||
if (retval) {
|
||||
printk(KERN_ERR "comedi: failed to create sysfs attribute file \"%s\".\n",
|
||||
dev_attr_read_buffer_kb.attr.name);
|
||||
printk(KERN_ERR
|
||||
"comedi: failed to create sysfs attribute file \"%s\".\n",
|
||||
dev_attr_read_buffer_kb.attr.name);
|
||||
comedi_free_subdevice_minor(s);
|
||||
return retval;
|
||||
}
|
||||
retval = device_create_file(csdev, &dev_attr_max_write_buffer_kb);
|
||||
if (retval) {
|
||||
printk(KERN_ERR "comedi: failed to create sysfs attribute file \"%s\".\n",
|
||||
dev_attr_max_write_buffer_kb.attr.name);
|
||||
printk(KERN_ERR
|
||||
"comedi: failed to create sysfs attribute file \"%s\".\n",
|
||||
dev_attr_max_write_buffer_kb.attr.name);
|
||||
comedi_free_subdevice_minor(s);
|
||||
return retval;
|
||||
}
|
||||
retval = device_create_file(csdev, &dev_attr_write_buffer_kb);
|
||||
if (retval) {
|
||||
printk(KERN_ERR "comedi: failed to create sysfs attribute file \"%s\".\n",
|
||||
dev_attr_write_buffer_kb.attr.name);
|
||||
printk(KERN_ERR
|
||||
"comedi: failed to create sysfs attribute file \"%s\".\n",
|
||||
dev_attr_write_buffer_kb.attr.name);
|
||||
comedi_free_subdevice_minor(s);
|
||||
return retval;
|
||||
}
|
||||
@@ -2295,7 +2323,7 @@ static int resize_async_buffer(struct comedi_device *dev,
|
||||
return -EINVAL;
|
||||
|
||||
/* make sure buffer is an integral number of pages
|
||||
* (we round up) */
|
||||
* (we round up) */
|
||||
new_size = (new_size + PAGE_SIZE - 1) & PAGE_MASK;
|
||||
|
||||
retval = comedi_buf_alloc(dev, s, new_size);
|
||||
@@ -2324,16 +2352,16 @@ static ssize_t show_max_read_buffer_kb(struct device *dev,
|
||||
struct comedi_device_file_info *info = dev_get_drvdata(dev);
|
||||
unsigned max_buffer_size_kb = 0;
|
||||
struct comedi_subdevice *const read_subdevice =
|
||||
comedi_get_read_subdevice(info);
|
||||
comedi_get_read_subdevice(info);
|
||||
|
||||
mutex_lock(&info->device->mutex);
|
||||
if (read_subdevice &&
|
||||
(read_subdevice->subdev_flags & SDF_CMD_READ) &&
|
||||
read_subdevice->async) {
|
||||
max_buffer_size_kb = read_subdevice->async->max_bufsize /
|
||||
bytes_per_kibi;
|
||||
bytes_per_kibi;
|
||||
}
|
||||
retval = snprintf(buf, PAGE_SIZE, "%i\n", max_buffer_size_kb);
|
||||
retval = snprintf(buf, PAGE_SIZE, "%i\n", max_buffer_size_kb);
|
||||
mutex_unlock(&info->device->mutex);
|
||||
|
||||
return retval;
|
||||
@@ -2347,14 +2375,14 @@ static ssize_t store_max_read_buffer_kb(struct device *dev,
|
||||
unsigned long new_max_size_kb;
|
||||
uint64_t new_max_size;
|
||||
struct comedi_subdevice *const read_subdevice =
|
||||
comedi_get_read_subdevice(info);
|
||||
comedi_get_read_subdevice(info);
|
||||
|
||||
if (strict_strtoul(buf, 10, &new_max_size_kb))
|
||||
return -EINVAL;
|
||||
if (new_max_size_kb != (uint32_t)new_max_size_kb)
|
||||
if (new_max_size_kb != (uint32_t) new_max_size_kb)
|
||||
return -EINVAL;
|
||||
new_max_size = ((uint64_t)new_max_size_kb) * bytes_per_kibi;
|
||||
if (new_max_size != (uint32_t)new_max_size)
|
||||
new_max_size = ((uint64_t) new_max_size_kb) * bytes_per_kibi;
|
||||
if (new_max_size != (uint32_t) new_max_size)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&info->device->mutex);
|
||||
@@ -2372,9 +2400,8 @@ static ssize_t store_max_read_buffer_kb(struct device *dev,
|
||||
|
||||
static struct device_attribute dev_attr_max_read_buffer_kb = {
|
||||
.attr = {
|
||||
.name = "max_read_buffer_kb",
|
||||
.mode = S_IRUGO | S_IWUSR
|
||||
},
|
||||
.name = "max_read_buffer_kb",
|
||||
.mode = S_IRUGO | S_IWUSR},
|
||||
.show = &show_max_read_buffer_kb,
|
||||
.store = &store_max_read_buffer_kb
|
||||
};
|
||||
@@ -2386,16 +2413,16 @@ static ssize_t show_read_buffer_kb(struct device *dev,
|
||||
struct comedi_device_file_info *info = dev_get_drvdata(dev);
|
||||
unsigned buffer_size_kb = 0;
|
||||
struct comedi_subdevice *const read_subdevice =
|
||||
comedi_get_read_subdevice(info);
|
||||
comedi_get_read_subdevice(info);
|
||||
|
||||
mutex_lock(&info->device->mutex);
|
||||
if (read_subdevice &&
|
||||
(read_subdevice->subdev_flags & SDF_CMD_READ) &&
|
||||
read_subdevice->async) {
|
||||
(read_subdevice->subdev_flags & SDF_CMD_READ) &&
|
||||
read_subdevice->async) {
|
||||
buffer_size_kb = read_subdevice->async->prealloc_bufsz /
|
||||
bytes_per_kibi;
|
||||
bytes_per_kibi;
|
||||
}
|
||||
retval = snprintf(buf, PAGE_SIZE, "%i\n", buffer_size_kb);
|
||||
retval = snprintf(buf, PAGE_SIZE, "%i\n", buffer_size_kb);
|
||||
mutex_unlock(&info->device->mutex);
|
||||
|
||||
return retval;
|
||||
@@ -2410,14 +2437,14 @@ static ssize_t store_read_buffer_kb(struct device *dev,
|
||||
uint64_t new_size;
|
||||
int retval;
|
||||
struct comedi_subdevice *const read_subdevice =
|
||||
comedi_get_read_subdevice(info);
|
||||
comedi_get_read_subdevice(info);
|
||||
|
||||
if (strict_strtoul(buf, 10, &new_size_kb))
|
||||
return -EINVAL;
|
||||
if (new_size_kb != (uint32_t)new_size_kb)
|
||||
if (new_size_kb != (uint32_t) new_size_kb)
|
||||
return -EINVAL;
|
||||
new_size = ((uint64_t)new_size_kb) * bytes_per_kibi;
|
||||
if (new_size != (uint32_t)new_size)
|
||||
new_size = ((uint64_t) new_size_kb) * bytes_per_kibi;
|
||||
if (new_size != (uint32_t) new_size)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&info->device->mutex);
|
||||
@@ -2438,9 +2465,8 @@ static ssize_t store_read_buffer_kb(struct device *dev,
|
||||
|
||||
static struct device_attribute dev_attr_read_buffer_kb = {
|
||||
.attr = {
|
||||
.name = "read_buffer_kb",
|
||||
.mode = S_IRUGO | S_IWUSR | S_IWGRP
|
||||
},
|
||||
.name = "read_buffer_kb",
|
||||
.mode = S_IRUGO | S_IWUSR | S_IWGRP},
|
||||
.show = &show_read_buffer_kb,
|
||||
.store = &store_read_buffer_kb
|
||||
};
|
||||
@@ -2453,16 +2479,16 @@ static ssize_t show_max_write_buffer_kb(struct device *dev,
|
||||
struct comedi_device_file_info *info = dev_get_drvdata(dev);
|
||||
unsigned max_buffer_size_kb = 0;
|
||||
struct comedi_subdevice *const write_subdevice =
|
||||
comedi_get_write_subdevice(info);
|
||||
comedi_get_write_subdevice(info);
|
||||
|
||||
mutex_lock(&info->device->mutex);
|
||||
if (write_subdevice &&
|
||||
(write_subdevice->subdev_flags & SDF_CMD_WRITE) &&
|
||||
write_subdevice->async) {
|
||||
max_buffer_size_kb = write_subdevice->async->max_bufsize /
|
||||
bytes_per_kibi;
|
||||
bytes_per_kibi;
|
||||
}
|
||||
retval = snprintf(buf, PAGE_SIZE, "%i\n", max_buffer_size_kb);
|
||||
retval = snprintf(buf, PAGE_SIZE, "%i\n", max_buffer_size_kb);
|
||||
mutex_unlock(&info->device->mutex);
|
||||
|
||||
return retval;
|
||||
@@ -2476,14 +2502,14 @@ static ssize_t store_max_write_buffer_kb(struct device *dev,
|
||||
unsigned long new_max_size_kb;
|
||||
uint64_t new_max_size;
|
||||
struct comedi_subdevice *const write_subdevice =
|
||||
comedi_get_write_subdevice(info);
|
||||
comedi_get_write_subdevice(info);
|
||||
|
||||
if (strict_strtoul(buf, 10, &new_max_size_kb))
|
||||
return -EINVAL;
|
||||
if (new_max_size_kb != (uint32_t)new_max_size_kb)
|
||||
if (new_max_size_kb != (uint32_t) new_max_size_kb)
|
||||
return -EINVAL;
|
||||
new_max_size = ((uint64_t)new_max_size_kb) * bytes_per_kibi;
|
||||
if (new_max_size != (uint32_t)new_max_size)
|
||||
new_max_size = ((uint64_t) new_max_size_kb) * bytes_per_kibi;
|
||||
if (new_max_size != (uint32_t) new_max_size)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&info->device->mutex);
|
||||
@@ -2501,9 +2527,8 @@ static ssize_t store_max_write_buffer_kb(struct device *dev,
|
||||
|
||||
static struct device_attribute dev_attr_max_write_buffer_kb = {
|
||||
.attr = {
|
||||
.name = "max_write_buffer_kb",
|
||||
.mode = S_IRUGO | S_IWUSR
|
||||
},
|
||||
.name = "max_write_buffer_kb",
|
||||
.mode = S_IRUGO | S_IWUSR},
|
||||
.show = &show_max_write_buffer_kb,
|
||||
.store = &store_max_write_buffer_kb
|
||||
};
|
||||
@@ -2515,16 +2540,16 @@ static ssize_t show_write_buffer_kb(struct device *dev,
|
||||
struct comedi_device_file_info *info = dev_get_drvdata(dev);
|
||||
unsigned buffer_size_kb = 0;
|
||||
struct comedi_subdevice *const write_subdevice =
|
||||
comedi_get_write_subdevice(info);
|
||||
comedi_get_write_subdevice(info);
|
||||
|
||||
mutex_lock(&info->device->mutex);
|
||||
if (write_subdevice &&
|
||||
(write_subdevice->subdev_flags & SDF_CMD_WRITE) &&
|
||||
write_subdevice->async) {
|
||||
buffer_size_kb = write_subdevice->async->prealloc_bufsz /
|
||||
bytes_per_kibi;
|
||||
bytes_per_kibi;
|
||||
}
|
||||
retval = snprintf(buf, PAGE_SIZE, "%i\n", buffer_size_kb);
|
||||
retval = snprintf(buf, PAGE_SIZE, "%i\n", buffer_size_kb);
|
||||
mutex_unlock(&info->device->mutex);
|
||||
|
||||
return retval;
|
||||
@@ -2539,14 +2564,14 @@ static ssize_t store_write_buffer_kb(struct device *dev,
|
||||
uint64_t new_size;
|
||||
int retval;
|
||||
struct comedi_subdevice *const write_subdevice =
|
||||
comedi_get_write_subdevice(info);
|
||||
comedi_get_write_subdevice(info);
|
||||
|
||||
if (strict_strtoul(buf, 10, &new_size_kb))
|
||||
return -EINVAL;
|
||||
if (new_size_kb != (uint32_t)new_size_kb)
|
||||
if (new_size_kb != (uint32_t) new_size_kb)
|
||||
return -EINVAL;
|
||||
new_size = ((uint64_t)new_size_kb) * bytes_per_kibi;
|
||||
if (new_size != (uint32_t)new_size)
|
||||
new_size = ((uint64_t) new_size_kb) * bytes_per_kibi;
|
||||
if (new_size != (uint32_t) new_size)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&info->device->mutex);
|
||||
@@ -2557,7 +2582,7 @@ static ssize_t store_write_buffer_kb(struct device *dev,
|
||||
return -EINVAL;
|
||||
}
|
||||
retval = resize_async_buffer(info->device, write_subdevice,
|
||||
write_subdevice->async, new_size);
|
||||
write_subdevice->async, new_size);
|
||||
mutex_unlock(&info->device->mutex);
|
||||
|
||||
if (retval < 0)
|
||||
@@ -2567,9 +2592,8 @@ static ssize_t store_write_buffer_kb(struct device *dev,
|
||||
|
||||
static struct device_attribute dev_attr_write_buffer_kb = {
|
||||
.attr = {
|
||||
.name = "write_buffer_kb",
|
||||
.mode = S_IRUGO | S_IWUSR | S_IWGRP
|
||||
},
|
||||
.name = "write_buffer_kb",
|
||||
.mode = S_IRUGO | S_IWUSR | S_IWGRP},
|
||||
.show = &show_write_buffer_kb,
|
||||
.store = &store_write_buffer_kb
|
||||
};
|
||||
|
||||
@@ -22,9 +22,6 @@
|
||||
*/
|
||||
|
||||
#define __NO_VERSION__
|
||||
#ifndef EXPORT_SYMTAB
|
||||
#define EXPORT_SYMTAB
|
||||
#endif
|
||||
|
||||
#include "comedidev.h"
|
||||
|
||||
|
||||
@@ -156,28 +156,30 @@ struct comedi_subdevice {
|
||||
|
||||
unsigned int *chanlist; /* driver-owned chanlist (not used) */
|
||||
|
||||
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 (*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) (struct comedi_device *, struct comedi_subdevice *);
|
||||
int (*do_cmdtest) (struct comedi_device *, struct comedi_subdevice *, struct comedi_cmd *);
|
||||
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) (struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
unsigned long new_size);
|
||||
int (*buf_change) (struct comedi_device * dev,
|
||||
struct comedi_subdevice * s, unsigned long new_size);
|
||||
|
||||
void (*munge) (struct comedi_device *dev, struct comedi_subdevice *s, void *data,
|
||||
unsigned int num_bytes, unsigned int start_chan_index);
|
||||
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;
|
||||
@@ -231,7 +233,7 @@ struct comedi_async {
|
||||
int (*cb_func) (unsigned int flags, void *);
|
||||
void *cb_arg;
|
||||
|
||||
int (*inttrig) (struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
int (*inttrig) (struct comedi_device * dev, struct comedi_subdevice * s,
|
||||
unsigned int x);
|
||||
};
|
||||
|
||||
@@ -281,8 +283,8 @@ struct comedi_device {
|
||||
|
||||
struct fasync_struct *async_queue;
|
||||
|
||||
void (*open) (struct comedi_device *dev);
|
||||
void (*close) (struct comedi_device *dev);
|
||||
void (*open) (struct comedi_device * dev);
|
||||
void (*close) (struct comedi_device * dev);
|
||||
};
|
||||
|
||||
struct comedi_device_file_info {
|
||||
@@ -316,8 +318,9 @@ static const unsigned COMEDI_SUBDEVICE_MINOR_OFFSET = 1;
|
||||
|
||||
struct comedi_device_file_info *comedi_get_device_file_info(unsigned minor);
|
||||
|
||||
static inline struct comedi_subdevice *comedi_get_read_subdevice(
|
||||
const struct comedi_device_file_info *info)
|
||||
static inline struct comedi_subdevice *comedi_get_read_subdevice(const struct
|
||||
comedi_device_file_info
|
||||
*info)
|
||||
{
|
||||
if (info->read_subdevice)
|
||||
return info->read_subdevice;
|
||||
@@ -326,8 +329,9 @@ static inline struct comedi_subdevice *comedi_get_read_subdevice(
|
||||
return info->device->read_subdev;
|
||||
}
|
||||
|
||||
static inline struct comedi_subdevice *comedi_get_write_subdevice(
|
||||
const struct comedi_device_file_info *info)
|
||||
static inline struct comedi_subdevice *comedi_get_write_subdevice(const struct
|
||||
comedi_device_file_info
|
||||
*info)
|
||||
{
|
||||
if (info->write_subdevice)
|
||||
return info->write_subdevice;
|
||||
@@ -337,7 +341,8 @@ static inline struct comedi_subdevice *comedi_get_write_subdevice(
|
||||
}
|
||||
|
||||
void comedi_device_detach(struct comedi_device *dev);
|
||||
int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
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 *);
|
||||
|
||||
@@ -346,8 +351,8 @@ void cleanup_polling(void);
|
||||
void start_polling(struct comedi_device *);
|
||||
void stop_polling(struct comedi_device *);
|
||||
|
||||
int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long
|
||||
new_size);
|
||||
int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
unsigned long new_size);
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
void comedi_proc_init(void);
|
||||
@@ -356,6 +361,7 @@ void comedi_proc_cleanup(void);
|
||||
static inline void comedi_proc_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void comedi_proc_cleanup(void)
|
||||
{
|
||||
}
|
||||
@@ -378,10 +384,10 @@ enum subdevice_runflags {
|
||||
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 bits);
|
||||
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);
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
/* range stuff */
|
||||
|
||||
@@ -421,7 +427,8 @@ static inline int alloc_subdevices(struct comedi_device *dev,
|
||||
|
||||
dev->n_subdevices = num_subdevices;
|
||||
dev->subdevices =
|
||||
kcalloc(num_subdevices, sizeof(struct 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) {
|
||||
@@ -451,7 +458,8 @@ static inline unsigned int bytes_per_sample(const struct comedi_subdevice *subd)
|
||||
|
||||
/* 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(struct 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);
|
||||
@@ -467,21 +475,23 @@ 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(struct comedi_async *async);
|
||||
unsigned int comedi_buf_write_alloc(struct comedi_async *async, unsigned int nbytes);
|
||||
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 int nbytes);
|
||||
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);
|
||||
const void *source, unsigned int num_bytes);
|
||||
void comedi_buf_memcpy_from(struct comedi_async *async, unsigned int offset,
|
||||
void *destination, unsigned int num_bytes);
|
||||
void *destination, unsigned int num_bytes);
|
||||
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(struct comedi_async *async)
|
||||
{
|
||||
return async->buf_read_alloc_count - async->buf_read_count;
|
||||
@@ -516,25 +526,26 @@ 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(struct comedi_device *dev, struct 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 */
|
||||
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);
|
||||
|
||||
#ifdef CONFIG_COMEDI_PCI_DRIVERS
|
||||
#define CONFIG_COMEDI_PCI
|
||||
#define CONFIG_COMEDI_PCI
|
||||
#endif
|
||||
#ifdef CONFIG_COMEDI_PCI_DRIVERS_MODULE
|
||||
#define CONFIG_COMEDI_PCI
|
||||
#define CONFIG_COMEDI_PCI
|
||||
#endif
|
||||
#ifdef CONFIG_COMEDI_PCMCIA_DRIVERS
|
||||
#define CONFIG_COMEDI_PCMCIA
|
||||
#define CONFIG_COMEDI_PCMCIA
|
||||
#endif
|
||||
#ifdef CONFIG_COMEDI_PCMCIA_DRIVERS_MODULE
|
||||
#define CONFIG_COMEDI_PCMCIA
|
||||
#define CONFIG_COMEDI_PCMCIA
|
||||
#endif
|
||||
|
||||
#endif /* _COMEDIDEV_H */
|
||||
|
||||
@@ -58,29 +58,31 @@ int comedi_fileno(void *dev);
|
||||
|
||||
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);
|
||||
unsigned int mask, int (*cb) (unsigned int,
|
||||
void *), void *arg);
|
||||
|
||||
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);
|
||||
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);
|
||||
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(void *dev, unsigned int subdev,
|
||||
unsigned int chan, unsigned int range, unsigned int aref,
|
||||
unsigned int *data, unsigned int nano_sec);
|
||||
unsigned int chan, unsigned int range,
|
||||
unsigned int aref);
|
||||
int comedi_data_read_delayed(void *dev, unsigned int subdev, unsigned int chan,
|
||||
unsigned int range, unsigned int aref,
|
||||
unsigned int *data, unsigned int nano_sec);
|
||||
int comedi_dio_config(void *dev, unsigned int subdev, unsigned int chan,
|
||||
unsigned int io);
|
||||
unsigned int io);
|
||||
int comedi_dio_read(void *dev, unsigned int subdev, unsigned int chan,
|
||||
unsigned int *val);
|
||||
unsigned int *val);
|
||||
int comedi_dio_write(void *dev, unsigned int subdev, unsigned int chan,
|
||||
unsigned int val);
|
||||
unsigned int val);
|
||||
int comedi_dio_bitfield(void *dev, unsigned int subdev, unsigned int mask,
|
||||
unsigned int *bits);
|
||||
unsigned int *bits);
|
||||
int comedi_get_n_subdevices(void *dev);
|
||||
int comedi_get_version_code(void *dev);
|
||||
const char *comedi_get_driver_name(void *dev);
|
||||
@@ -89,31 +91,29 @@ 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(void *dev, unsigned int subdevice, unsigned int
|
||||
chan);
|
||||
int chan);
|
||||
int comedi_get_n_ranges(void *dev, unsigned int subdevice, unsigned int chan);
|
||||
int comedi_do_insn(void *dev, struct comedi_insn *insn);
|
||||
int comedi_poll(void *dev, unsigned int subdev);
|
||||
|
||||
/* DEPRECATED functions */
|
||||
int comedi_get_rangetype(void *dev, unsigned int subdevice,
|
||||
unsigned int chan);
|
||||
int comedi_get_rangetype(void *dev, unsigned int subdevice, unsigned int chan);
|
||||
|
||||
/* ALPHA functions */
|
||||
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);
|
||||
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);
|
||||
unsigned int buf_user_count);
|
||||
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);
|
||||
unsigned int num_bytes);
|
||||
int comedi_mark_buffer_written(void *d, unsigned int subdevice,
|
||||
unsigned int num_bytes);
|
||||
unsigned int num_bytes);
|
||||
int comedi_get_buffer_contents(void *dev, unsigned int subdevice);
|
||||
int comedi_get_buffer_offset(void *dev, unsigned int subdevice);
|
||||
|
||||
@@ -135,53 +135,56 @@ int comedi_unlock(unsigned int minor, unsigned int subdev);
|
||||
|
||||
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);
|
||||
unsigned int mask, int (*cb) (unsigned int,
|
||||
void *), void *arg);
|
||||
|
||||
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_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, unsigned int 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, unsigned int *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);
|
||||
unsigned int io);
|
||||
int comedi_dio_read(unsigned int dev, unsigned int subdev, unsigned int chan,
|
||||
unsigned int *val);
|
||||
unsigned int *val);
|
||||
int comedi_dio_write(unsigned int dev, unsigned int subdev, unsigned int chan,
|
||||
unsigned int val);
|
||||
unsigned int val);
|
||||
int comedi_dio_bitfield(unsigned int dev, unsigned int subdev,
|
||||
unsigned int mask, unsigned int *bits);
|
||||
unsigned int mask, unsigned int *bits);
|
||||
int comedi_get_n_subdevices(unsigned int dev);
|
||||
int comedi_get_version_code(unsigned int dev);
|
||||
char *comedi_get_driver_name(unsigned int dev);
|
||||
char *comedi_get_board_name(unsigned int minor);
|
||||
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);
|
||||
unsigned int subd);
|
||||
int comedi_get_n_channels(unsigned int minor, unsigned int subdevice);
|
||||
unsigned int comedi_get_maxdata(unsigned int minor, unsigned int subdevice, unsigned
|
||||
int chan);
|
||||
int chan);
|
||||
int comedi_get_n_ranges(unsigned int minor, unsigned int subdevice, unsigned int
|
||||
chan);
|
||||
chan);
|
||||
int comedi_do_insn(unsigned int minor, struct comedi_insn *insn);
|
||||
int comedi_poll(unsigned int minor, unsigned int subdev);
|
||||
|
||||
/* DEPRECATED functions */
|
||||
int comedi_get_rangetype(unsigned int minor, unsigned int subdevice,
|
||||
unsigned int chan);
|
||||
unsigned int chan);
|
||||
|
||||
/* ALPHA functions */
|
||||
unsigned int comedi_get_subdevice_flags(unsigned int minor, unsigned int
|
||||
subdevice);
|
||||
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, struct comedi_krange *krange);
|
||||
chan, unsigned int range, struct comedi_krange *krange);
|
||||
unsigned int comedi_get_buf_head_pos(unsigned int minor, unsigned int
|
||||
subdevice);
|
||||
subdevice);
|
||||
int comedi_set_user_int_count(unsigned int minor, unsigned int subdevice,
|
||||
unsigned int buf_user_count);
|
||||
unsigned int buf_user_count);
|
||||
int comedi_map(unsigned int minor, unsigned int subdev, void **ptr);
|
||||
int comedi_unmap(unsigned int minor, unsigned int subdev);
|
||||
|
||||
|
||||
@@ -48,13 +48,14 @@
|
||||
#include <asm/system.h>
|
||||
|
||||
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 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);
|
||||
unsigned long new_size);
|
||||
|
||||
struct comedi_driver *comedi_drivers;
|
||||
|
||||
@@ -123,7 +124,8 @@ int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
|
||||
for (driv = comedi_drivers; driv; driv = driv->next) {
|
||||
if (!try_module_get(driv->module)) {
|
||||
printk("comedi: failed to increment module count, skipping\n");
|
||||
printk
|
||||
("comedi: failed to increment module count, skipping\n");
|
||||
continue;
|
||||
}
|
||||
if (driv->num_names) {
|
||||
@@ -195,16 +197,20 @@ int comedi_driver_unregister(struct comedi_driver *driver)
|
||||
|
||||
/* 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);
|
||||
struct comedi_device_file_info *dev_file_info =
|
||||
comedi_get_device_file_info(i);
|
||||
struct comedi_device *dev;
|
||||
|
||||
if (dev_file_info == NULL) continue;
|
||||
if (dev_file_info == NULL)
|
||||
continue;
|
||||
dev = dev_file_info->device;
|
||||
|
||||
mutex_lock(&dev->mutex);
|
||||
if (dev->attached && dev->driver == driver) {
|
||||
if (dev->use_count)
|
||||
printk("BUG! detaching device with use_count=%d\n", dev->use_count);
|
||||
printk
|
||||
("BUG! detaching device with use_count=%d\n",
|
||||
dev->use_count);
|
||||
comedi_device_detach(dev);
|
||||
}
|
||||
mutex_unlock(&dev->mutex);
|
||||
@@ -242,10 +248,11 @@ static int postconfig(struct comedi_device *dev)
|
||||
|
||||
if (s->do_cmd) {
|
||||
BUG_ON((s->subdev_flags & (SDF_CMD_READ |
|
||||
SDF_CMD_WRITE)) == 0);
|
||||
SDF_CMD_WRITE)) == 0);
|
||||
BUG_ON(!s->do_cmdtest);
|
||||
|
||||
async = kzalloc(sizeof(struct 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,7 +305,7 @@ static int postconfig(struct comedi_device *dev)
|
||||
}
|
||||
|
||||
/* generic recognize function for drivers that register their supported board names */
|
||||
void *comedi_recognize(struct comedi_driver * driv, const char *name)
|
||||
void *comedi_recognize(struct comedi_driver *driv, const char *name)
|
||||
{
|
||||
unsigned i;
|
||||
const char *const *name_ptr = driv->board_name;
|
||||
@@ -306,8 +313,8 @@ void *comedi_recognize(struct comedi_driver * driv, const char *name)
|
||||
if (strcmp(*name_ptr, name) == 0)
|
||||
return (void *)name_ptr;
|
||||
name_ptr =
|
||||
(const char *const *)((const char *)name_ptr +
|
||||
driv->offset);
|
||||
(const char *const *)((const char *)name_ptr +
|
||||
driv->offset);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -319,7 +326,7 @@ void comedi_report_boards(struct comedi_driver *driv)
|
||||
const char *const *name_ptr;
|
||||
|
||||
printk("comedi: valid board names for %s driver are:\n",
|
||||
driv->driver_name);
|
||||
driv->driver_name);
|
||||
|
||||
name_ptr = driv->board_name;
|
||||
for (i = 0; i < driv->num_names; i++) {
|
||||
@@ -337,13 +344,14 @@ static int poll_invalid(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
}
|
||||
|
||||
int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int insn_rw_emulate_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int insn_rw_emulate_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
struct comedi_insn new_insn;
|
||||
int ret;
|
||||
@@ -351,7 +359,7 @@ static int insn_rw_emulate_bits(struct comedi_device *dev, struct comedi_subdevi
|
||||
|
||||
unsigned chan = CR_CHAN(insn->chanspec);
|
||||
const unsigned base_bitfield_channel =
|
||||
(chan < channels_per_bitfield) ? 0 : chan;
|
||||
(chan < channels_per_bitfield) ? 0 : chan;
|
||||
unsigned int new_data[2];
|
||||
memset(new_data, 0, sizeof(new_data));
|
||||
memset(&new_insn, 0, sizeof(new_insn));
|
||||
@@ -379,7 +387,7 @@ static int insn_rw_emulate_bits(struct comedi_device *dev, struct comedi_subdevi
|
||||
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;
|
||||
@@ -394,7 +402,7 @@ static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr)
|
||||
pte = *ptep;
|
||||
if (pte_present(pte)) {
|
||||
ret = (unsigned long)
|
||||
page_address(pte_page(pte));
|
||||
page_address(pte_page(pte));
|
||||
ret |= (adr & (PAGE_SIZE - 1));
|
||||
}
|
||||
}
|
||||
@@ -413,7 +421,7 @@ static inline unsigned long kvirt_to_kva(unsigned long adr)
|
||||
}
|
||||
|
||||
int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
unsigned long new_size)
|
||||
unsigned long new_size)
|
||||
{
|
||||
struct comedi_async *async = s->async;
|
||||
|
||||
@@ -434,18 +442,22 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
unsigned i;
|
||||
for (i = 0; i < async->n_buf_pages; ++i) {
|
||||
if (async->buf_page_list[i].virt_addr) {
|
||||
mem_map_unreserve(virt_to_page(async->
|
||||
buf_page_list[i].virt_addr));
|
||||
mem_map_unreserve(virt_to_page
|
||||
(async->buf_page_list[i].
|
||||
virt_addr));
|
||||
if (s->async_dma_dir != DMA_NONE) {
|
||||
dma_free_coherent(dev->hw_dev,
|
||||
PAGE_SIZE,
|
||||
async->buf_page_list[i].
|
||||
virt_addr,
|
||||
async->buf_page_list[i].
|
||||
dma_addr);
|
||||
PAGE_SIZE,
|
||||
async->
|
||||
buf_page_list
|
||||
[i].virt_addr,
|
||||
async->
|
||||
buf_page_list
|
||||
[i].dma_addr);
|
||||
} else {
|
||||
free_page((unsigned long)async->
|
||||
buf_page_list[i].virt_addr);
|
||||
free_page((unsigned long)
|
||||
async->buf_page_list[i].
|
||||
virt_addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -460,66 +472,69 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct page **pages = NULL;
|
||||
|
||||
async->buf_page_list =
|
||||
vmalloc(sizeof(struct comedi_buf_page) * n_pages);
|
||||
vmalloc(sizeof(struct comedi_buf_page) * n_pages);
|
||||
if (async->buf_page_list) {
|
||||
memset(async->buf_page_list, 0,
|
||||
sizeof(struct comedi_buf_page) * n_pages);
|
||||
sizeof(struct comedi_buf_page) * n_pages);
|
||||
pages = vmalloc(sizeof(struct page *) * n_pages);
|
||||
}
|
||||
if (pages) {
|
||||
for (i = 0; i < n_pages; i++) {
|
||||
if (s->async_dma_dir != DMA_NONE) {
|
||||
async->buf_page_list[i].virt_addr =
|
||||
dma_alloc_coherent(dev->hw_dev,
|
||||
PAGE_SIZE,
|
||||
&async->buf_page_list[i].
|
||||
dma_addr,
|
||||
GFP_KERNEL | __GFP_COMP);
|
||||
dma_alloc_coherent(dev->hw_dev,
|
||||
PAGE_SIZE,
|
||||
&async->
|
||||
buf_page_list
|
||||
[i].dma_addr,
|
||||
GFP_KERNEL |
|
||||
__GFP_COMP);
|
||||
} else {
|
||||
async->buf_page_list[i].virt_addr =
|
||||
(void *)
|
||||
get_zeroed_page(GFP_KERNEL);
|
||||
(void *)
|
||||
get_zeroed_page(GFP_KERNEL);
|
||||
}
|
||||
if (async->buf_page_list[i].virt_addr == NULL) {
|
||||
break;
|
||||
}
|
||||
mem_map_reserve(virt_to_page(async->
|
||||
buf_page_list[i].virt_addr));
|
||||
mem_map_reserve(virt_to_page
|
||||
(async->buf_page_list[i].
|
||||
virt_addr));
|
||||
pages[i] =
|
||||
virt_to_page(async->buf_page_list[i].
|
||||
virt_addr);
|
||||
virt_to_page(async->
|
||||
buf_page_list[i].virt_addr);
|
||||
}
|
||||
}
|
||||
if (i == n_pages) {
|
||||
async->prealloc_buf =
|
||||
vmap(pages, n_pages, VM_MAP,
|
||||
PAGE_KERNEL_NOCACHE);
|
||||
}
|
||||
if (pages) {
|
||||
vfree(pages);
|
||||
vmap(pages, n_pages, VM_MAP, PAGE_KERNEL_NOCACHE);
|
||||
}
|
||||
vfree(pages);
|
||||
|
||||
if (async->prealloc_buf == NULL) {
|
||||
/* Some allocation failed above. */
|
||||
if (async->buf_page_list) {
|
||||
for (i = 0; i < n_pages; i++) {
|
||||
if (async->buf_page_list[i].virt_addr ==
|
||||
NULL) {
|
||||
NULL) {
|
||||
break;
|
||||
}
|
||||
mem_map_unreserve(virt_to_page(async->
|
||||
buf_page_list[i].
|
||||
virt_addr));
|
||||
mem_map_unreserve(virt_to_page
|
||||
(async->buf_page_list
|
||||
[i].virt_addr));
|
||||
if (s->async_dma_dir != DMA_NONE) {
|
||||
dma_free_coherent(dev->hw_dev,
|
||||
PAGE_SIZE,
|
||||
async->buf_page_list[i].
|
||||
virt_addr,
|
||||
async->buf_page_list[i].
|
||||
dma_addr);
|
||||
PAGE_SIZE,
|
||||
async->
|
||||
buf_page_list
|
||||
[i].virt_addr,
|
||||
async->
|
||||
buf_page_list
|
||||
[i].dma_addr);
|
||||
} else {
|
||||
free_page((unsigned long)async->
|
||||
buf_page_list[i].
|
||||
virt_addr);
|
||||
free_page((unsigned long)
|
||||
async->buf_page_list
|
||||
[i].virt_addr);
|
||||
}
|
||||
}
|
||||
vfree(async->buf_page_list);
|
||||
@@ -536,7 +551,8 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
|
||||
/* munging is applied to data by core as it passes between user
|
||||
* and kernel space */
|
||||
unsigned int comedi_buf_munge(struct comedi_async *async, unsigned int num_bytes)
|
||||
unsigned int comedi_buf_munge(struct comedi_async *async,
|
||||
unsigned int num_bytes)
|
||||
{
|
||||
struct comedi_subdevice *s = async->subdevice;
|
||||
unsigned int count = 0;
|
||||
@@ -555,15 +571,15 @@ unsigned int comedi_buf_munge(struct comedi_async *async, unsigned int num_bytes
|
||||
block_size = num_bytes - count;
|
||||
if (block_size < 0) {
|
||||
printk("%s: %s: bug! block_size is negative\n",
|
||||
__FILE__, __func__);
|
||||
__FILE__, __func__);
|
||||
break;
|
||||
}
|
||||
if ((int)(async->munge_ptr + block_size -
|
||||
async->prealloc_bufsz) > 0)
|
||||
async->prealloc_bufsz) > 0)
|
||||
block_size = async->prealloc_bufsz - async->munge_ptr;
|
||||
|
||||
s->munge(s->device, s, async->prealloc_buf + async->munge_ptr,
|
||||
block_size, async->munge_chan);
|
||||
block_size, async->munge_chan);
|
||||
|
||||
smp_wmb(); /* barrier insures data is munged in buffer before munge_count is incremented */
|
||||
|
||||
@@ -598,7 +614,8 @@ unsigned int comedi_buf_write_n_available(struct comedi_async *async)
|
||||
}
|
||||
|
||||
/* allocates chunk for the writer from free buffer space */
|
||||
unsigned int comedi_buf_write_alloc(struct 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;
|
||||
|
||||
@@ -614,7 +631,7 @@ unsigned int comedi_buf_write_alloc(struct comedi_async *async, unsigned int nby
|
||||
|
||||
/* allocates nothing unless it can completely fulfill the request */
|
||||
unsigned int comedi_buf_write_alloc_strict(struct comedi_async *async,
|
||||
unsigned int nbytes)
|
||||
unsigned int nbytes)
|
||||
{
|
||||
unsigned int free_end = async->buf_read_count + async->prealloc_bufsz;
|
||||
|
||||
@@ -632,8 +649,9 @@ unsigned int comedi_buf_write_alloc_strict(struct comedi_async *async,
|
||||
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) {
|
||||
printk("comedi: attempted to write-free more bytes than have been write-allocated.\n");
|
||||
async->buf_write_alloc_count) > 0) {
|
||||
printk
|
||||
("comedi: attempted to write-free more bytes than have been write-allocated.\n");
|
||||
nbytes = async->buf_write_alloc_count - async->buf_write_count;
|
||||
}
|
||||
async->buf_write_count += nbytes;
|
||||
@@ -649,7 +667,7 @@ unsigned comedi_buf_write_free(struct comedi_async *async, unsigned int nbytes)
|
||||
unsigned comedi_buf_read_alloc(struct comedi_async *async, unsigned nbytes)
|
||||
{
|
||||
if ((int)(async->buf_read_alloc_count + nbytes - async->munge_count) >
|
||||
0) {
|
||||
0) {
|
||||
nbytes = async->munge_count - async->buf_read_alloc_count;
|
||||
}
|
||||
async->buf_read_alloc_count += nbytes;
|
||||
@@ -665,8 +683,9 @@ 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 */
|
||||
smp_mb();
|
||||
if ((int)(async->buf_read_count + nbytes -
|
||||
async->buf_read_alloc_count) > 0) {
|
||||
printk("comedi: attempted to read-free more bytes than have been read-allocated.\n");
|
||||
async->buf_read_alloc_count) > 0) {
|
||||
printk
|
||||
("comedi: attempted to read-free more bytes than have been read-allocated.\n");
|
||||
nbytes = async->buf_read_alloc_count - async->buf_read_count;
|
||||
}
|
||||
async->buf_read_count += nbytes;
|
||||
@@ -676,7 +695,7 @@ unsigned comedi_buf_read_free(struct comedi_async *async, unsigned int nbytes)
|
||||
}
|
||||
|
||||
void comedi_buf_memcpy_to(struct comedi_async *async, unsigned int offset,
|
||||
const void *data, unsigned int num_bytes)
|
||||
const void *data, unsigned int num_bytes)
|
||||
{
|
||||
unsigned int write_ptr = async->buf_write_ptr + offset;
|
||||
|
||||
@@ -701,7 +720,7 @@ void comedi_buf_memcpy_to(struct comedi_async *async, unsigned int offset,
|
||||
}
|
||||
|
||||
void comedi_buf_memcpy_from(struct comedi_async *async, unsigned int offset,
|
||||
void *dest, unsigned int nbytes)
|
||||
void *dest, unsigned int nbytes)
|
||||
{
|
||||
void *src;
|
||||
unsigned int read_ptr = async->buf_read_ptr + offset;
|
||||
@@ -748,7 +767,7 @@ int comedi_buf_get(struct comedi_async *async, short *x)
|
||||
if (n < sizeof(short))
|
||||
return 0;
|
||||
comedi_buf_read_alloc(async, sizeof(short));
|
||||
*x = *(short *) (async->prealloc_buf + async->buf_read_ptr);
|
||||
*x = *(short *)(async->prealloc_buf + async->buf_read_ptr);
|
||||
comedi_buf_read_free(async, sizeof(short));
|
||||
return 1;
|
||||
}
|
||||
@@ -761,7 +780,7 @@ int comedi_buf_put(struct comedi_async *async, short x)
|
||||
async->events |= COMEDI_CB_ERROR;
|
||||
return 0;
|
||||
}
|
||||
*(short *) (async->prealloc_buf + async->buf_write_ptr) = x;
|
||||
*(short *)(async->prealloc_buf + async->buf_write_ptr) = x;
|
||||
comedi_buf_write_free(async, sizeof(short));
|
||||
return 1;
|
||||
}
|
||||
@@ -785,7 +804,8 @@ void comedi_reset_async_buf(struct comedi_async *async)
|
||||
async->events = 0;
|
||||
}
|
||||
|
||||
int comedi_auto_config(struct device *hardware_device, const char *board_name, const int *options, unsigned num_options)
|
||||
int comedi_auto_config(struct device *hardware_device, const char *board_name,
|
||||
const int *options, unsigned num_options)
|
||||
{
|
||||
struct comedi_devconfig it;
|
||||
int minor;
|
||||
@@ -799,7 +819,8 @@ int comedi_auto_config(struct device *hardware_device, const char *board_name, c
|
||||
}
|
||||
|
||||
minor = comedi_alloc_board_minor(hardware_device);
|
||||
if (minor < 0) return minor;
|
||||
if (minor < 0)
|
||||
return minor;
|
||||
|
||||
private_data = kmalloc(sizeof(unsigned), GFP_KERNEL);
|
||||
if (private_data == NULL) {
|
||||
@@ -822,8 +843,7 @@ int comedi_auto_config(struct device *hardware_device, const char *board_name, c
|
||||
mutex_unlock(&dev_file_info->device->mutex);
|
||||
|
||||
cleanup:
|
||||
if (retval < 0)
|
||||
{
|
||||
if (retval < 0) {
|
||||
kfree(private_data);
|
||||
comedi_free_board_minor(minor);
|
||||
}
|
||||
@@ -833,7 +853,8 @@ int comedi_auto_config(struct device *hardware_device, const char *board_name, c
|
||||
void comedi_auto_unconfig(struct device *hardware_device)
|
||||
{
|
||||
unsigned *minor = (unsigned *)dev_get_drvdata(hardware_device);
|
||||
if (minor == NULL) return;
|
||||
if (minor == NULL)
|
||||
return;
|
||||
|
||||
BUG_ON(*minor >= COMEDI_NUM_BOARD_MINORS);
|
||||
|
||||
@@ -860,8 +881,7 @@ 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)
|
||||
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);
|
||||
|
||||
@@ -29,8 +29,10 @@
|
||||
#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)
|
||||
unsigned int *d1,
|
||||
unsigned int *d2,
|
||||
unsigned int *nanosec,
|
||||
int round_mode)
|
||||
{
|
||||
int divider;
|
||||
int div1, div2;
|
||||
@@ -78,8 +80,10 @@ static inline void i8253_cascade_ns_to_timer_2div_old(int i8253_osc_base,
|
||||
}
|
||||
|
||||
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)
|
||||
unsigned int *d1,
|
||||
unsigned int *d2,
|
||||
unsigned int *nanosec,
|
||||
int round_mode)
|
||||
{
|
||||
int div1, div2;
|
||||
int base;
|
||||
@@ -118,8 +122,10 @@ static inline void i8253_cascade_ns_to_timer_power(int i8253_osc_base,
|
||||
}
|
||||
|
||||
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 *d1,
|
||||
unsigned int *d2,
|
||||
unsigned int *nanosec,
|
||||
int round_mode)
|
||||
{
|
||||
unsigned int divider;
|
||||
unsigned int div1, div2;
|
||||
@@ -136,12 +142,11 @@ static inline void i8253_cascade_ns_to_timer_2div(int i8253_osc_base,
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -158,10 +163,10 @@ static inline void i8253_cascade_ns_to_timer_2div(int i8253_osc_base,
|
||||
if (start < 2)
|
||||
start = 2;
|
||||
for (div1 = start; div1 <= divider / div1 + 1 && div1 <= max_count;
|
||||
div1++) {
|
||||
div1++) {
|
||||
for (div2 = divider / div1;
|
||||
div1 * div2 <= divider + div1 + 1 && div2 <= max_count;
|
||||
div2++) {
|
||||
div1 * div2 <= divider + div1 + 1 && div2 <= max_count;
|
||||
div2++) {
|
||||
ns = i8253_osc_base * div1 * div2;
|
||||
if (ns <= *nanosec && ns > ns_glb) {
|
||||
ns_glb = ns;
|
||||
@@ -229,7 +234,8 @@ static inline void i8253_cascade_ns_to_timer_2div(int i8253_osc_base,
|
||||
#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 counter_number, unsigned int count,
|
||||
unsigned int mode)
|
||||
{
|
||||
unsigned int byte;
|
||||
|
||||
@@ -255,7 +261,8 @@ static inline int i8254_load(unsigned long base_address, unsigned int regshift,
|
||||
}
|
||||
|
||||
static inline int i8254_mm_load(void *base_address, unsigned int regshift,
|
||||
unsigned int counter_number, unsigned int count, unsigned int mode)
|
||||
unsigned int counter_number, unsigned int count,
|
||||
unsigned int mode)
|
||||
{
|
||||
unsigned int byte;
|
||||
|
||||
@@ -282,7 +289,7 @@ static inline int i8254_mm_load(void *base_address, unsigned int regshift,
|
||||
|
||||
/* 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 counter_number)
|
||||
{
|
||||
unsigned int byte;
|
||||
int ret;
|
||||
@@ -303,7 +310,7 @@ static inline int i8254_read(unsigned long base_address, unsigned int regshift,
|
||||
}
|
||||
|
||||
static inline int i8254_mm_read(void *base_address, unsigned int regshift,
|
||||
unsigned int counter_number)
|
||||
unsigned int counter_number)
|
||||
{
|
||||
unsigned int byte;
|
||||
int ret;
|
||||
@@ -325,7 +332,8 @@ static inline int i8254_mm_read(void *base_address, unsigned int regshift,
|
||||
|
||||
/* 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 regshift,
|
||||
unsigned int counter_number, unsigned int count)
|
||||
{
|
||||
unsigned int byte;
|
||||
|
||||
@@ -339,7 +347,9 @@ static inline void i8254_write(unsigned long base_address,
|
||||
}
|
||||
|
||||
static inline void i8254_mm_write(void *base_address,
|
||||
unsigned int regshift, unsigned int counter_number, unsigned int count)
|
||||
unsigned int regshift,
|
||||
unsigned int counter_number,
|
||||
unsigned int count)
|
||||
{
|
||||
unsigned int byte;
|
||||
|
||||
@@ -360,7 +370,8 @@ static inline void i8254_mm_write(void *base_address,
|
||||
* 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 regshift,
|
||||
unsigned int counter_number, unsigned int mode)
|
||||
{
|
||||
unsigned int byte;
|
||||
|
||||
@@ -378,7 +389,9 @@ static inline int i8254_set_mode(unsigned long base_address,
|
||||
}
|
||||
|
||||
static inline int i8254_mm_set_mode(void *base_address,
|
||||
unsigned int regshift, unsigned int counter_number, unsigned int mode)
|
||||
unsigned int regshift,
|
||||
unsigned int counter_number,
|
||||
unsigned int mode)
|
||||
{
|
||||
unsigned int byte;
|
||||
|
||||
@@ -396,18 +409,20 @@ static inline int i8254_mm_set_mode(void *base_address,
|
||||
}
|
||||
|
||||
static inline int i8254_status(unsigned long base_address,
|
||||
unsigned int regshift, unsigned int counter_number)
|
||||
unsigned int regshift,
|
||||
unsigned int counter_number)
|
||||
{
|
||||
outb(0xE0 | (2 << counter_number),
|
||||
base_address + (i8254_control_reg << regshift));
|
||||
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)
|
||||
unsigned int regshift,
|
||||
unsigned int counter_number)
|
||||
{
|
||||
writeb(0xE0 | (2 << counter_number),
|
||||
base_address + (i8254_control_reg << regshift));
|
||||
base_address + (i8254_control_reg << regshift));
|
||||
return readb(base_address + (counter_number << regshift));
|
||||
}
|
||||
|
||||
|
||||
@@ -105,7 +105,8 @@ struct subdev_8255_struct {
|
||||
#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_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",
|
||||
@@ -116,9 +117,10 @@ static struct comedi_driver driver_8255 = {
|
||||
|
||||
COMEDI_INITCLEANUP(driver_8255);
|
||||
|
||||
static void do_config(struct comedi_device *dev, struct comedi_subdevice * s);
|
||||
static void do_config(struct comedi_device *dev, struct comedi_subdevice *s);
|
||||
|
||||
void subdev_8255_interrupt(struct comedi_device *dev, struct comedi_subdevice * s)
|
||||
void subdev_8255_interrupt(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
short d;
|
||||
|
||||
@@ -143,8 +145,9 @@ static int subdev_8255_cb(int dir, int port, int data, unsigned long arg)
|
||||
}
|
||||
}
|
||||
|
||||
static int subdev_8255_insn(struct comedi_device *dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
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];
|
||||
@@ -152,13 +155,13 @@ static int subdev_8255_insn(struct comedi_device *dev, struct comedi_subdevice *
|
||||
|
||||
if (data[0] & 0xff)
|
||||
CALLBACK_FUNC(1, _8255_DATA, s->state & 0xff,
|
||||
CALLBACK_ARG);
|
||||
CALLBACK_ARG);
|
||||
if (data[0] & 0xff00)
|
||||
CALLBACK_FUNC(1, _8255_DATA + 1, (s->state >> 8) & 0xff,
|
||||
CALLBACK_ARG);
|
||||
CALLBACK_ARG);
|
||||
if (data[0] & 0xff0000)
|
||||
CALLBACK_FUNC(1, _8255_DATA + 2,
|
||||
(s->state >> 16) & 0xff, CALLBACK_ARG);
|
||||
(s->state >> 16) & 0xff, CALLBACK_ARG);
|
||||
}
|
||||
|
||||
data[1] = CALLBACK_FUNC(0, _8255_DATA, 0, CALLBACK_ARG);
|
||||
@@ -168,8 +171,9 @@ static int subdev_8255_insn(struct comedi_device *dev, struct comedi_subdevice *
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int subdev_8255_insn_config(struct comedi_device *dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
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;
|
||||
@@ -205,7 +209,7 @@ static int subdev_8255_insn_config(struct comedi_device *dev, struct comedi_subd
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void do_config(struct comedi_device *dev, struct comedi_subdevice * s)
|
||||
static void do_config(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
{
|
||||
int config;
|
||||
|
||||
@@ -222,8 +226,9 @@ static void do_config(struct comedi_device *dev, struct comedi_subdevice * s)
|
||||
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)
|
||||
static int subdev_8255_cmdtest(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd)
|
||||
{
|
||||
int err = 0;
|
||||
unsigned int tmp;
|
||||
@@ -297,22 +302,25 @@ static int subdev_8255_cmdtest(struct comedi_device *dev, struct comedi_subdevic
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int subdev_8255_cmd(struct comedi_device *dev, struct comedi_subdevice * s)
|
||||
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)
|
||||
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)
|
||||
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;
|
||||
@@ -340,8 +348,9 @@ int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice * s, int
|
||||
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 subdev_8255_init_irq(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
int (*cb) (int, int, int, unsigned long),
|
||||
unsigned long arg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -358,7 +367,7 @@ int subdev_8255_init_irq(struct comedi_device *dev, struct comedi_subdevice * s,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void subdev_8255_cleanup(struct comedi_device *dev, struct comedi_subdevice * s)
|
||||
void subdev_8255_cleanup(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
{
|
||||
if (s->private) {
|
||||
/* this test does nothing, so comment it out
|
||||
@@ -376,7 +385,8 @@ void subdev_8255_cleanup(struct comedi_device *dev, struct comedi_subdevice * s)
|
||||
|
||||
*/
|
||||
|
||||
static int dev_8255_attach(struct comedi_device *dev, struct comedi_devconfig * it)
|
||||
static int dev_8255_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it)
|
||||
{
|
||||
int ret;
|
||||
unsigned long iobase;
|
||||
@@ -410,7 +420,7 @@ static int dev_8255_attach(struct comedi_device *dev, struct comedi_devconfig *
|
||||
dev->subdevices[i].type = COMEDI_SUBD_UNUSED;
|
||||
} else {
|
||||
subdev_8255_init(dev, dev->subdevices + i, NULL,
|
||||
iobase);
|
||||
iobase);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,16 +29,20 @@
|
||||
#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 (*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);
|
||||
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);
|
||||
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)
|
||||
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");
|
||||
|
||||
@@ -48,7 +52,7 @@ static inline int subdev_8255_init(struct comedi_device *dev, struct comedi_subd
|
||||
}
|
||||
|
||||
static inline void subdev_8255_cleanup(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,8 @@ Devices: [Adlink] ACL-7225b (acl7225b), [ICP] P16R16DIO (p16r16dio)
|
||||
#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_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int acl7225b_detach(struct comedi_device *dev);
|
||||
|
||||
struct boardtype {
|
||||
@@ -50,8 +51,9 @@ static struct comedi_driver driver_acl7225b = {
|
||||
|
||||
COMEDI_INITCLEANUP(driver_acl7225b);
|
||||
|
||||
static int acl7225b_do_insn(struct comedi_device *dev, struct comedi_subdevice * s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
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;
|
||||
@@ -64,26 +66,28 @@ static int acl7225b_do_insn(struct comedi_device *dev, struct comedi_subdevice *
|
||||
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);
|
||||
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)
|
||||
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);
|
||||
(inb(dev->iobase + (unsigned long)s->private + 1) << 8);
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int acl7225b_attach(struct comedi_device *dev, struct comedi_devconfig * it)
|
||||
static int acl7225b_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it)
|
||||
{
|
||||
struct comedi_subdevice *s;
|
||||
int iobase, iorange;
|
||||
@@ -91,7 +95,7 @@ static int acl7225b_attach(struct comedi_device *dev, struct comedi_devconfig *
|
||||
iobase = it->options[0];
|
||||
iorange = this_board->io_range;
|
||||
printk("comedi%d: acl7225b: board=%s 0x%04x ", dev->minor,
|
||||
this_board->name, iobase);
|
||||
this_board->name, iobase);
|
||||
if (!request_region(iobase, iorange, "acl7225b")) {
|
||||
printk("I/O port conflict\n");
|
||||
return -EIO;
|
||||
|
||||
@@ -261,6 +261,9 @@ void v_pci_card_list_init(unsigned short pci_vendor, char display)
|
||||
pci_vendor = i_ADDIDATADeviceID[i_Count];
|
||||
if (pcidev->vendor == pci_vendor) {
|
||||
amcc = kmalloc(sizeof(*amcc), GFP_KERNEL);
|
||||
if (amcc == NULL)
|
||||
continue;
|
||||
|
||||
memset(amcc, 0, sizeof(*amcc));
|
||||
|
||||
amcc->pcidev = pcidev;
|
||||
|
||||
@@ -254,6 +254,9 @@ void v_pci_card_list_init(unsigned short pci_vendor, char display)
|
||||
pci_for_each_dev(pcidev) {
|
||||
if (pcidev->vendor == pci_vendor) {
|
||||
amcc = kmalloc(sizeof(*amcc), GFP_KERNEL);
|
||||
if (amcc == NULL)
|
||||
continue;
|
||||
|
||||
memset(amcc, 0, sizeof(*amcc));
|
||||
|
||||
amcc->pcidev = pcidev;
|
||||
|
||||
@@ -2669,7 +2669,7 @@ int i_APCI3200_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_s
|
||||
err++;
|
||||
printk("\nThe Delay time base selection is in error\n");
|
||||
}
|
||||
if (ui_DelayTime < 1 && ui_DelayTime > 1023) {
|
||||
if (ui_DelayTime < 1 || ui_DelayTime > 1023) {
|
||||
err++;
|
||||
printk("\nThe Delay time value is in error\n");
|
||||
}
|
||||
|
||||
@@ -66,23 +66,23 @@ struct pci6208_board {
|
||||
|
||||
static const struct pci6208_board pci6208_boards[] = {
|
||||
/*{
|
||||
.name = "pci6208v",
|
||||
.dev_id = 0x6208, // not sure
|
||||
.ao_chans = 8
|
||||
// , .ao_bits = 16
|
||||
.name = "pci6208v",
|
||||
.dev_id = 0x6208, // not sure
|
||||
.ao_chans = 8
|
||||
// , .ao_bits = 16
|
||||
},
|
||||
{
|
||||
.name = "pci6216v",
|
||||
.dev_id = 0x6208, // not sure
|
||||
.ao_chans = 16
|
||||
// , .ao_bits = 16
|
||||
.name = "pci6216v",
|
||||
.dev_id = 0x6208, // not sure
|
||||
.ao_chans = 16
|
||||
// , .ao_bits = 16
|
||||
}, */
|
||||
{
|
||||
.name = "pci6208a",
|
||||
.dev_id = 0x6208,
|
||||
.ao_chans = 8
|
||||
/* , .ao_bits = 16 */
|
||||
}
|
||||
.name = "pci6208a",
|
||||
.dev_id = 0x6208,
|
||||
.ao_chans = 8
|
||||
/* , .ao_bits = 16 */
|
||||
}
|
||||
};
|
||||
|
||||
/* This is used by modprobe to translate PCI IDs to drivers. Should
|
||||
@@ -90,8 +90,9 @@ static const struct pci6208_board pci6208_boards[] = {
|
||||
static DEFINE_PCI_DEVICE_TABLE(pci6208_pci_table) = {
|
||||
/* { PCI_VENDOR_ID_ADLINK, 0x6208, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, */
|
||||
/* { PCI_VENDOR_ID_ADLINK, 0x6208, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, */
|
||||
{PCI_VENDOR_ID_ADLINK, 0x6208, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{0}
|
||||
{
|
||||
PCI_VENDOR_ID_ADLINK, 0x6208, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
0}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, pci6208_pci_table);
|
||||
@@ -107,7 +108,8 @@ struct pci6208_private {
|
||||
|
||||
#define devpriv ((struct pci6208_private *)dev->private)
|
||||
|
||||
static int pci6208_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int pci6208_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int pci6208_detach(struct comedi_device *dev);
|
||||
|
||||
static struct comedi_driver driver_pci6208 = {
|
||||
@@ -122,13 +124,15 @@ COMEDI_PCI_INITCLEANUP(driver_pci6208, pci6208_pci_table);
|
||||
static int pci6208_find_device(struct comedi_device *dev, int bus, int slot);
|
||||
static int
|
||||
pci6208_pci_setup(struct pci_dev *pci_dev, unsigned long *io_base_ptr,
|
||||
int dev_minor);
|
||||
int dev_minor);
|
||||
|
||||
/*read/write functions*/
|
||||
static int pci6208_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int pci6208_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int pci6208_ao_winsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int pci6208_ao_rinsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
/* static int pci6208_dio_insn_bits(struct comedi_device *dev,struct comedi_subdevice *s, */
|
||||
/* struct comedi_insn *insn,unsigned int *data); */
|
||||
/* static int pci6208_dio_insn_config(struct comedi_device *dev,struct comedi_subdevice *s, */
|
||||
@@ -140,7 +144,8 @@ static int pci6208_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *
|
||||
* in the driver structure, dev->board_ptr contains that
|
||||
* address.
|
||||
*/
|
||||
static int pci6208_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
static int pci6208_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it)
|
||||
{
|
||||
struct comedi_subdevice *s;
|
||||
int retval;
|
||||
@@ -217,8 +222,9 @@ static int pci6208_detach(struct comedi_device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pci6208_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int pci6208_ao_winsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int i = 0, Data_Read;
|
||||
unsigned short chan = CR_CHAN(insn->chanspec);
|
||||
@@ -242,8 +248,9 @@ static int pci6208_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *
|
||||
|
||||
/* AO subdevices should have a read insn as well as a write insn.
|
||||
* Usually this means copying a value stored in devpriv. */
|
||||
static int pci6208_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int pci6208_ao_rinsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int i;
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
@@ -309,8 +316,8 @@ static int pci6208_find_device(struct comedi_device *dev, int bus, int slot)
|
||||
int i;
|
||||
|
||||
for (pci_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
|
||||
pci_dev != NULL;
|
||||
pci_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) {
|
||||
pci_dev != NULL;
|
||||
pci_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) {
|
||||
if (pci_dev->vendor == PCI_VENDOR_ID_ADLINK) {
|
||||
for (i = 0; i < ARRAY_SIZE(pci6208_boards); i++) {
|
||||
if (pci6208_boards[i].dev_id == pci_dev->device) {
|
||||
@@ -318,9 +325,9 @@ static int pci6208_find_device(struct comedi_device *dev, int bus, int slot)
|
||||
if ((bus != 0) || (slot != 0)) {
|
||||
/* are we on the wrong bus/slot? */
|
||||
if (pci_dev->bus->number
|
||||
!= bus ||
|
||||
PCI_SLOT(pci_dev->devfn)
|
||||
!= slot) {
|
||||
!= bus ||
|
||||
PCI_SLOT(pci_dev->devfn)
|
||||
!= slot) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -332,16 +339,16 @@ static int pci6208_find_device(struct comedi_device *dev, int bus, int slot)
|
||||
}
|
||||
|
||||
printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
|
||||
dev->minor, bus, slot);
|
||||
dev->minor, bus, slot);
|
||||
return -EIO;
|
||||
|
||||
found:
|
||||
found:
|
||||
printk("comedi%d: found %s (b:s:f=%d:%d:%d) , irq=%d\n",
|
||||
dev->minor,
|
||||
pci6208_boards[i].name,
|
||||
pci_dev->bus->number,
|
||||
PCI_SLOT(pci_dev->devfn),
|
||||
PCI_FUNC(pci_dev->devfn), pci_dev->irq);
|
||||
dev->minor,
|
||||
pci6208_boards[i].name,
|
||||
pci_dev->bus->number,
|
||||
PCI_SLOT(pci_dev->devfn),
|
||||
PCI_FUNC(pci_dev->devfn), pci_dev->irq);
|
||||
|
||||
/* TODO: Warn about non-tested boards. */
|
||||
/* switch(board->device_id) */
|
||||
@@ -355,13 +362,15 @@ static int pci6208_find_device(struct comedi_device *dev, int bus, int slot)
|
||||
|
||||
static int
|
||||
pci6208_pci_setup(struct pci_dev *pci_dev, unsigned long *io_base_ptr,
|
||||
int dev_minor)
|
||||
int dev_minor)
|
||||
{
|
||||
unsigned long io_base, io_range, lcr_io_base, lcr_io_range;
|
||||
|
||||
/* Enable PCI device and request regions */
|
||||
if (comedi_pci_enable(pci_dev, PCI6208_DRIVER_NAME) < 0) {
|
||||
printk("comedi%d: Failed to enable PCI device and request regions\n", dev_minor);
|
||||
printk
|
||||
("comedi%d: Failed to enable PCI device and request regions\n",
|
||||
dev_minor);
|
||||
return -EIO;
|
||||
}
|
||||
/* Read local configuration register base address [PCI_BASE_ADDRESS #1]. */
|
||||
@@ -369,14 +378,14 @@ pci6208_pci_setup(struct pci_dev *pci_dev, unsigned long *io_base_ptr,
|
||||
lcr_io_range = pci_resource_len(pci_dev, 1);
|
||||
|
||||
printk("comedi%d: local config registers at address 0x%4lx [0x%4lx]\n",
|
||||
dev_minor, lcr_io_base, lcr_io_range);
|
||||
dev_minor, lcr_io_base, lcr_io_range);
|
||||
|
||||
/* Read PCI6208 register base address [PCI_BASE_ADDRESS #2]. */
|
||||
io_base = pci_resource_start(pci_dev, 2);
|
||||
io_range = pci_resource_end(pci_dev, 2) - io_base + 1;
|
||||
|
||||
printk("comedi%d: 6208 registers at address 0x%4lx [0x%4lx]\n",
|
||||
dev_minor, io_base, io_range);
|
||||
dev_minor, io_base, io_range);
|
||||
|
||||
*io_base_ptr = io_base;
|
||||
/* devpriv->io_range = io_range; */
|
||||
|
||||
@@ -49,9 +49,10 @@ Configuration Options:
|
||||
#define PCI_DEVICE_ID_PCI7296 0x7296
|
||||
|
||||
static DEFINE_PCI_DEVICE_TABLE(adl_pci7296_pci_table) = {
|
||||
{PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7296, PCI_ANY_ID, PCI_ANY_ID, 0,
|
||||
0, 0},
|
||||
{0}
|
||||
{
|
||||
PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7296, PCI_ANY_ID,
|
||||
PCI_ANY_ID, 0, 0, 0}, {
|
||||
0}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, adl_pci7296_pci_table);
|
||||
@@ -61,10 +62,10 @@ struct adl_pci7296_private {
|
||||
struct pci_dev *pci_dev;
|
||||
};
|
||||
|
||||
|
||||
#define devpriv ((struct adl_pci7296_private *)dev->private)
|
||||
|
||||
static int adl_pci7296_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int adl_pci7296_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int adl_pci7296_detach(struct comedi_device *dev);
|
||||
static struct comedi_driver driver_adl_pci7296 = {
|
||||
.driver_name = "adl_pci7296",
|
||||
@@ -73,7 +74,8 @@ static struct comedi_driver driver_adl_pci7296 = {
|
||||
.detach = adl_pci7296_detach,
|
||||
};
|
||||
|
||||
static int adl_pci7296_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
static int adl_pci7296_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it)
|
||||
{
|
||||
struct pci_dev *pcidev;
|
||||
struct comedi_subdevice *s;
|
||||
@@ -94,21 +96,23 @@ static int adl_pci7296_attach(struct comedi_device *dev, struct comedi_devconfig
|
||||
return -ENOMEM;
|
||||
|
||||
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)) {
|
||||
pcidev != NULL;
|
||||
pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
|
||||
|
||||
if (pcidev->vendor == PCI_VENDOR_ID_ADLINK &&
|
||||
pcidev->device == PCI_DEVICE_ID_PCI7296) {
|
||||
pcidev->device == PCI_DEVICE_ID_PCI7296) {
|
||||
if (bus || slot) {
|
||||
/* requested particular bus/slot */
|
||||
if (pcidev->bus->number != bus
|
||||
|| PCI_SLOT(pcidev->devfn) != slot) {
|
||||
|| PCI_SLOT(pcidev->devfn) != slot) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
devpriv->pci_dev = pcidev;
|
||||
if (comedi_pci_enable(pcidev, "adl_pci7296") < 0) {
|
||||
printk("comedi%d: Failed to enable PCI device and request regions\n", dev->minor);
|
||||
printk
|
||||
("comedi%d: Failed to enable PCI device and request regions\n",
|
||||
dev->minor);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@@ -118,23 +122,26 @@ static int adl_pci7296_attach(struct comedi_device *dev, struct comedi_devconfig
|
||||
/* four 8255 digital io subdevices */
|
||||
s = dev->subdevices + 0;
|
||||
subdev_8255_init(dev, s, NULL,
|
||||
(unsigned long)(dev->iobase));
|
||||
(unsigned long)(dev->iobase));
|
||||
|
||||
s = dev->subdevices + 1;
|
||||
ret = subdev_8255_init(dev, s, NULL,
|
||||
(unsigned long)(dev->iobase + PORT2A));
|
||||
(unsigned long)(dev->iobase +
|
||||
PORT2A));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
s = dev->subdevices + 2;
|
||||
ret = subdev_8255_init(dev, s, NULL,
|
||||
(unsigned long)(dev->iobase + PORT3A));
|
||||
(unsigned long)(dev->iobase +
|
||||
PORT3A));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
s = dev->subdevices + 3;
|
||||
ret = subdev_8255_init(dev, s, NULL,
|
||||
(unsigned long)(dev->iobase + PORT4A));
|
||||
(unsigned long)(dev->iobase +
|
||||
PORT4A));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@@ -145,7 +152,7 @@ static int adl_pci7296_attach(struct comedi_device *dev, struct comedi_devconfig
|
||||
}
|
||||
|
||||
printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
|
||||
dev->minor, bus, slot);
|
||||
dev->minor, bus, slot);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,9 +44,10 @@ Configuration Options:
|
||||
#define PCI_DEVICE_ID_PCI7432 0x7432
|
||||
|
||||
static DEFINE_PCI_DEVICE_TABLE(adl_pci7432_pci_table) = {
|
||||
{PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7432, PCI_ANY_ID, PCI_ANY_ID, 0,
|
||||
0, 0},
|
||||
{0}
|
||||
{
|
||||
PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7432, PCI_ANY_ID,
|
||||
PCI_ANY_ID, 0, 0, 0}, {
|
||||
0}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, adl_pci7432_pci_table);
|
||||
@@ -58,7 +59,8 @@ struct adl_pci7432_private {
|
||||
|
||||
#define devpriv ((struct adl_pci7432_private *)dev->private)
|
||||
|
||||
static int adl_pci7432_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int adl_pci7432_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int adl_pci7432_detach(struct comedi_device *dev);
|
||||
static struct comedi_driver driver_adl_pci7432 = {
|
||||
.driver_name = "adl_pci7432",
|
||||
@@ -69,15 +71,20 @@ static struct comedi_driver driver_adl_pci7432 = {
|
||||
|
||||
/* Digital IO */
|
||||
|
||||
static int adl_pci7432_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int adl_pci7432_di_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
|
||||
static int adl_pci7432_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int adl_pci7432_do_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
|
||||
/* */
|
||||
|
||||
static int adl_pci7432_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
static int adl_pci7432_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it)
|
||||
{
|
||||
struct pci_dev *pcidev;
|
||||
struct comedi_subdevice *s;
|
||||
@@ -97,21 +104,23 @@ static int adl_pci7432_attach(struct comedi_device *dev, struct comedi_devconfig
|
||||
return -ENOMEM;
|
||||
|
||||
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)) {
|
||||
pcidev != NULL;
|
||||
pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
|
||||
|
||||
if (pcidev->vendor == PCI_VENDOR_ID_ADLINK &&
|
||||
pcidev->device == PCI_DEVICE_ID_PCI7432) {
|
||||
pcidev->device == PCI_DEVICE_ID_PCI7432) {
|
||||
if (bus || slot) {
|
||||
/* requested particular bus/slot */
|
||||
if (pcidev->bus->number != bus
|
||||
|| PCI_SLOT(pcidev->devfn) != slot) {
|
||||
|| PCI_SLOT(pcidev->devfn) != slot) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
devpriv->pci_dev = pcidev;
|
||||
if (comedi_pci_enable(pcidev, "adl_pci7432") < 0) {
|
||||
printk("comedi%d: Failed to enable PCI device and request regions\n", dev->minor);
|
||||
printk
|
||||
("comedi%d: Failed to enable PCI device and request regions\n",
|
||||
dev->minor);
|
||||
return -EIO;
|
||||
}
|
||||
dev->iobase = pci_resource_start(pcidev, 2);
|
||||
@@ -120,7 +129,7 @@ static int adl_pci7432_attach(struct comedi_device *dev, struct comedi_devconfig
|
||||
s = dev->subdevices + 0;
|
||||
s->type = COMEDI_SUBD_DI;
|
||||
s->subdev_flags =
|
||||
SDF_READABLE | SDF_GROUND | SDF_COMMON;
|
||||
SDF_READABLE | SDF_GROUND | SDF_COMMON;
|
||||
s->n_chan = 32;
|
||||
s->maxdata = 1;
|
||||
s->len_chanlist = 32;
|
||||
@@ -131,7 +140,7 @@ static int adl_pci7432_attach(struct comedi_device *dev, struct comedi_devconfig
|
||||
s = dev->subdevices + 1;
|
||||
s->type = COMEDI_SUBD_DO;
|
||||
s->subdev_flags =
|
||||
SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
|
||||
SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
|
||||
s->n_chan = 32;
|
||||
s->maxdata = 1;
|
||||
s->len_chanlist = 32;
|
||||
@@ -146,7 +155,7 @@ static int adl_pci7432_attach(struct comedi_device *dev, struct comedi_devconfig
|
||||
}
|
||||
|
||||
printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
|
||||
dev->minor, bus, slot);
|
||||
dev->minor, bus, slot);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@@ -164,8 +173,10 @@ static int adl_pci7432_detach(struct comedi_device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int adl_pci7432_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int adl_pci7432_do_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
printk("comedi: pci7432_do_insn_bits called\n");
|
||||
printk("comedi: data0: %8x data1: %8x\n", data[0], data[1]);
|
||||
@@ -178,14 +189,16 @@ static int adl_pci7432_do_insn_bits(struct comedi_device *dev, struct comedi_sub
|
||||
s->state |= (data[0] & data[1]);
|
||||
|
||||
printk("comedi: out: %8x on iobase %4lx\n", s->state,
|
||||
dev->iobase + PCI7432_DO);
|
||||
dev->iobase + PCI7432_DO);
|
||||
outl(s->state & 0xffffffff, dev->iobase + PCI7432_DO);
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int adl_pci7432_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int adl_pci7432_di_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
printk("comedi: pci7432_di_insn_bits called\n");
|
||||
printk("comedi: data0: %8x data1: %8x\n", data[0], data[1]);
|
||||
|
||||
@@ -56,9 +56,10 @@ Configuration Options:
|
||||
#define PCI_DEVICE_ID_PCI8164 0x8164
|
||||
|
||||
static DEFINE_PCI_DEVICE_TABLE(adl_pci8164_pci_table) = {
|
||||
{PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI8164, PCI_ANY_ID, PCI_ANY_ID, 0,
|
||||
0, 0},
|
||||
{0}
|
||||
{
|
||||
PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI8164, PCI_ANY_ID,
|
||||
PCI_ANY_ID, 0, 0, 0}, {
|
||||
0}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, adl_pci8164_pci_table);
|
||||
@@ -70,7 +71,8 @@ struct adl_pci8164_private {
|
||||
|
||||
#define devpriv ((struct adl_pci8164_private *)dev->private)
|
||||
|
||||
static int adl_pci8164_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int adl_pci8164_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int adl_pci8164_detach(struct comedi_device *dev);
|
||||
static struct comedi_driver driver_adl_pci8164 = {
|
||||
.driver_name = "adl_pci8164",
|
||||
@@ -79,31 +81,48 @@ static struct comedi_driver driver_adl_pci8164 = {
|
||||
.detach = adl_pci8164_detach,
|
||||
};
|
||||
|
||||
static int adl_pci8164_insn_read_msts(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int adl_pci8164_insn_read_msts(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
|
||||
static int adl_pci8164_insn_read_ssts(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int adl_pci8164_insn_read_ssts(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
|
||||
static int adl_pci8164_insn_read_buf0(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int adl_pci8164_insn_read_buf0(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
|
||||
static int adl_pci8164_insn_read_buf1(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int adl_pci8164_insn_read_buf1(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
|
||||
static int adl_pci8164_insn_write_cmd(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int adl_pci8164_insn_write_cmd(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
|
||||
static int adl_pci8164_insn_write_otp(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int adl_pci8164_insn_write_otp(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
|
||||
static int adl_pci8164_insn_write_buf0(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
|
||||
static int adl_pci8164_insn_write_buf1(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
|
||||
static int adl_pci8164_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
static int adl_pci8164_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it)
|
||||
{
|
||||
struct pci_dev *pcidev;
|
||||
struct comedi_subdevice *s;
|
||||
@@ -123,21 +142,23 @@ static int adl_pci8164_attach(struct comedi_device *dev, struct comedi_devconfig
|
||||
return -ENOMEM;
|
||||
|
||||
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)) {
|
||||
pcidev != NULL;
|
||||
pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
|
||||
|
||||
if (pcidev->vendor == PCI_VENDOR_ID_ADLINK &&
|
||||
pcidev->device == PCI_DEVICE_ID_PCI8164) {
|
||||
pcidev->device == PCI_DEVICE_ID_PCI8164) {
|
||||
if (bus || slot) {
|
||||
/* requested particular bus/slot */
|
||||
if (pcidev->bus->number != bus
|
||||
|| PCI_SLOT(pcidev->devfn) != slot) {
|
||||
|| PCI_SLOT(pcidev->devfn) != slot) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
devpriv->pci_dev = pcidev;
|
||||
if (comedi_pci_enable(pcidev, "adl_pci8164") < 0) {
|
||||
printk("comedi%d: Failed to enable PCI device and request regions\n", dev->minor);
|
||||
printk
|
||||
("comedi%d: Failed to enable PCI device and request regions\n",
|
||||
dev->minor);
|
||||
return -EIO;
|
||||
}
|
||||
dev->iobase = pci_resource_start(pcidev, 2);
|
||||
@@ -190,7 +211,7 @@ static int adl_pci8164_attach(struct comedi_device *dev, struct comedi_devconfig
|
||||
}
|
||||
|
||||
printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
|
||||
dev->minor, bus, slot);
|
||||
dev->minor, bus, slot);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@@ -216,8 +237,7 @@ static void adl_pci8164_insn_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data,
|
||||
char *action,
|
||||
unsigned short offset)
|
||||
char *action, unsigned short offset)
|
||||
{
|
||||
int axis, axis_reg;
|
||||
char *axisname;
|
||||
@@ -247,8 +267,8 @@ static void adl_pci8164_insn_read(struct comedi_device *dev,
|
||||
}
|
||||
|
||||
data[0] = inw(dev->iobase + axis_reg + offset);
|
||||
printk("comedi: pci8164 %s read -> %04X:%04X on axis %s\n", action, data[0],
|
||||
data[1], axisname);
|
||||
printk("comedi: pci8164 %s read -> %04X:%04X on axis %s\n", action,
|
||||
data[0], data[1], axisname);
|
||||
}
|
||||
|
||||
static int adl_pci8164_insn_read_msts(struct comedi_device *dev,
|
||||
@@ -260,22 +280,28 @@ static int adl_pci8164_insn_read_msts(struct comedi_device *dev,
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int adl_pci8164_insn_read_ssts(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int adl_pci8164_insn_read_ssts(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
adl_pci8164_insn_read(dev, s, insn, data, "SSTS", PCI8164_SSTS);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int adl_pci8164_insn_read_buf0(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int adl_pci8164_insn_read_buf0(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
adl_pci8164_insn_read(dev, s, insn, data, "BUF0", PCI8164_BUF0);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int adl_pci8164_insn_read_buf1(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int adl_pci8164_insn_read_buf1(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
adl_pci8164_insn_read(dev, s, insn, data, "BUF1", PCI8164_BUF1);
|
||||
return 2;
|
||||
@@ -286,11 +312,10 @@ static int adl_pci8164_insn_read_buf1(struct comedi_device *dev, struct comedi_s
|
||||
* const to the data for outw()
|
||||
*/
|
||||
static void adl_pci8164_insn_out(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data,
|
||||
char *action,
|
||||
unsigned short offset)
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data,
|
||||
char *action, unsigned short offset)
|
||||
{
|
||||
unsigned int axis, axis_reg;
|
||||
|
||||
@@ -327,30 +352,37 @@ static void adl_pci8164_insn_out(struct comedi_device *dev,
|
||||
|
||||
}
|
||||
|
||||
|
||||
static int adl_pci8164_insn_write_cmd(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int adl_pci8164_insn_write_cmd(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
adl_pci8164_insn_out(dev, s, insn, data, "CMD", PCI8164_CMD);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int adl_pci8164_insn_write_otp(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int adl_pci8164_insn_write_otp(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
adl_pci8164_insn_out(dev, s, insn, data, "OTP", PCI8164_OTP);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int adl_pci8164_insn_write_buf0(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
adl_pci8164_insn_out(dev, s, insn, data, "BUF0", PCI8164_BUF0);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int adl_pci8164_insn_write_buf1(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
adl_pci8164_insn_out(dev, s, insn, data, "BUF1", PCI8164_BUF1);
|
||||
return 2;
|
||||
|
||||
@@ -264,27 +264,32 @@ Configuration options:
|
||||
|
||||
/* Function prototypes */
|
||||
|
||||
static int pci9111_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int pci9111_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int pci9111_detach(struct comedi_device *dev);
|
||||
static void pci9111_ai_munge(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
void *data, unsigned int num_bytes, unsigned int start_chan_index);
|
||||
static void pci9111_ai_munge(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, void *data,
|
||||
unsigned int num_bytes,
|
||||
unsigned int start_chan_index);
|
||||
|
||||
static const struct comedi_lrange pci9111_hr_ai_range = {
|
||||
5,
|
||||
{
|
||||
BIP_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(2.5),
|
||||
BIP_RANGE(1.25),
|
||||
BIP_RANGE(0.625)
|
||||
}
|
||||
BIP_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(2.5),
|
||||
BIP_RANGE(1.25),
|
||||
BIP_RANGE(0.625)
|
||||
}
|
||||
};
|
||||
|
||||
static DEFINE_PCI_DEVICE_TABLE(pci9111_pci_table) = {
|
||||
{PCI_VENDOR_ID_ADLINK, PCI9111_HR_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0,
|
||||
0, 0},
|
||||
/* { PCI_VENDOR_ID_ADLINK, PCI9111_HG_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, */
|
||||
{0}
|
||||
{
|
||||
PCI_VENDOR_ID_ADLINK, PCI9111_HR_DEVICE_ID, PCI_ANY_ID,
|
||||
PCI_ANY_ID, 0, 0, 0},
|
||||
/* { PCI_VENDOR_ID_ADLINK, PCI9111_HG_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, */
|
||||
{
|
||||
0}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, pci9111_pci_table);
|
||||
@@ -309,17 +314,17 @@ struct pci9111_board {
|
||||
|
||||
static const struct pci9111_board pci9111_boards[] = {
|
||||
{
|
||||
.name = "pci9111_hr",
|
||||
.device_id = PCI9111_HR_DEVICE_ID,
|
||||
.ai_channel_nbr = PCI9111_AI_CHANNEL_NBR,
|
||||
.ao_channel_nbr = PCI9111_AO_CHANNEL_NBR,
|
||||
.ai_resolution = PCI9111_HR_AI_RESOLUTION,
|
||||
.ai_resolution_mask = PCI9111_HR_AI_RESOLUTION_MASK,
|
||||
.ao_resolution = PCI9111_AO_RESOLUTION,
|
||||
.ao_resolution_mask = PCI9111_AO_RESOLUTION_MASK,
|
||||
.ai_range_list = &pci9111_hr_ai_range,
|
||||
.ao_range_list = &range_bipolar10,
|
||||
.ai_acquisition_period_min_ns = PCI9111_AI_ACQUISITION_PERIOD_MIN_NS}
|
||||
.name = "pci9111_hr",
|
||||
.device_id = PCI9111_HR_DEVICE_ID,
|
||||
.ai_channel_nbr = PCI9111_AI_CHANNEL_NBR,
|
||||
.ao_channel_nbr = PCI9111_AO_CHANNEL_NBR,
|
||||
.ai_resolution = PCI9111_HR_AI_RESOLUTION,
|
||||
.ai_resolution_mask = PCI9111_HR_AI_RESOLUTION_MASK,
|
||||
.ao_resolution = PCI9111_AO_RESOLUTION,
|
||||
.ao_resolution_mask = PCI9111_AO_RESOLUTION_MASK,
|
||||
.ai_range_list = &pci9111_hr_ai_range,
|
||||
.ao_range_list = &range_bipolar10,
|
||||
.ai_acquisition_period_min_ns = PCI9111_AI_ACQUISITION_PERIOD_MIN_NS}
|
||||
};
|
||||
|
||||
#define pci9111_board_nbr \
|
||||
@@ -379,9 +384,11 @@ struct pci9111_private_data {
|
||||
#define PLX9050_SOFTWARE_INTERRUPT (1 << 7)
|
||||
|
||||
static void plx9050_interrupt_control(unsigned long io_base,
|
||||
bool LINTi1_enable,
|
||||
bool LINTi1_active_high,
|
||||
bool LINTi2_enable, bool LINTi2_active_high, bool interrupt_enable)
|
||||
bool LINTi1_enable,
|
||||
bool LINTi1_active_high,
|
||||
bool LINTi2_enable,
|
||||
bool LINTi2_active_high,
|
||||
bool interrupt_enable)
|
||||
{
|
||||
int flags = 0;
|
||||
|
||||
@@ -409,16 +416,19 @@ static void plx9050_interrupt_control(unsigned long io_base,
|
||||
static void pci9111_timer_set(struct comedi_device *dev)
|
||||
{
|
||||
pci9111_8254_control_set(PCI9111_8254_COUNTER_0 |
|
||||
PCI9111_8254_READ_LOAD_LSB_MSB |
|
||||
PCI9111_8254_MODE_0 | PCI9111_8254_BINARY_COUNTER);
|
||||
PCI9111_8254_READ_LOAD_LSB_MSB |
|
||||
PCI9111_8254_MODE_0 |
|
||||
PCI9111_8254_BINARY_COUNTER);
|
||||
|
||||
pci9111_8254_control_set(PCI9111_8254_COUNTER_1 |
|
||||
PCI9111_8254_READ_LOAD_LSB_MSB |
|
||||
PCI9111_8254_MODE_2 | PCI9111_8254_BINARY_COUNTER);
|
||||
PCI9111_8254_READ_LOAD_LSB_MSB |
|
||||
PCI9111_8254_MODE_2 |
|
||||
PCI9111_8254_BINARY_COUNTER);
|
||||
|
||||
pci9111_8254_control_set(PCI9111_8254_COUNTER_2 |
|
||||
PCI9111_8254_READ_LOAD_LSB_MSB |
|
||||
PCI9111_8254_MODE_2 | PCI9111_8254_BINARY_COUNTER);
|
||||
PCI9111_8254_READ_LOAD_LSB_MSB |
|
||||
PCI9111_8254_MODE_2 |
|
||||
PCI9111_8254_BINARY_COUNTER);
|
||||
|
||||
udelay(1);
|
||||
|
||||
@@ -433,7 +443,7 @@ enum pci9111_trigger_sources {
|
||||
};
|
||||
|
||||
static void pci9111_trigger_source_set(struct comedi_device *dev,
|
||||
enum pci9111_trigger_sources source)
|
||||
enum pci9111_trigger_sources source)
|
||||
{
|
||||
int flags;
|
||||
|
||||
@@ -491,7 +501,8 @@ enum pci9111_ISC1_sources {
|
||||
};
|
||||
|
||||
static void pci9111_interrupt_source_set(struct comedi_device *dev,
|
||||
enum pci9111_ISC0_sources irq_0_source, enum pci9111_ISC1_sources irq_1_source)
|
||||
enum pci9111_ISC0_sources irq_0_source,
|
||||
enum pci9111_ISC1_sources irq_1_source)
|
||||
{
|
||||
int flags;
|
||||
|
||||
@@ -514,12 +525,13 @@ static void pci9111_interrupt_source_set(struct comedi_device *dev,
|
||||
|
||||
#undef AI_DO_CMD_DEBUG
|
||||
|
||||
static int pci9111_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
static int pci9111_ai_cancel(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
/* Disable interrupts */
|
||||
|
||||
plx9050_interrupt_control(dev_private->lcr_io_base, true, true, true,
|
||||
true, false);
|
||||
true, false);
|
||||
|
||||
pci9111_trigger_source_set(dev, software);
|
||||
|
||||
@@ -543,19 +555,19 @@ static int pci9111_ai_cancel(struct comedi_device *dev, struct comedi_subdevice
|
||||
|
||||
static int
|
||||
pci9111_ai_do_cmd_test(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_cmd *cmd)
|
||||
struct comedi_subdevice *s, struct comedi_cmd *cmd)
|
||||
{
|
||||
int tmp;
|
||||
int error = 0;
|
||||
int range, reference;
|
||||
int i;
|
||||
struct pci9111_board *board = (struct pci9111_board *) dev->board_ptr;
|
||||
struct pci9111_board *board = (struct pci9111_board *)dev->board_ptr;
|
||||
|
||||
/* Step 1 : check if trigger are trivialy valid */
|
||||
|
||||
pci9111_check_trigger_src(cmd->start_src, TRIG_NOW);
|
||||
pci9111_check_trigger_src(cmd->scan_begin_src,
|
||||
TRIG_TIMER | TRIG_FOLLOW | TRIG_EXT);
|
||||
TRIG_TIMER | TRIG_FOLLOW | TRIG_EXT);
|
||||
pci9111_check_trigger_src(cmd->convert_src, TRIG_TIMER | TRIG_EXT);
|
||||
pci9111_check_trigger_src(cmd->scan_end_src, TRIG_COUNT);
|
||||
pci9111_check_trigger_src(cmd->stop_src, TRIG_COUNT | TRIG_NONE);
|
||||
@@ -569,21 +581,21 @@ pci9111_ai_do_cmd_test(struct comedi_device *dev,
|
||||
error++;
|
||||
|
||||
if ((cmd->scan_begin_src != TRIG_TIMER) &&
|
||||
(cmd->scan_begin_src != TRIG_FOLLOW) &&
|
||||
(cmd->scan_begin_src != TRIG_EXT))
|
||||
(cmd->scan_begin_src != TRIG_FOLLOW) &&
|
||||
(cmd->scan_begin_src != TRIG_EXT))
|
||||
error++;
|
||||
|
||||
if ((cmd->convert_src != TRIG_TIMER) && (cmd->convert_src != TRIG_EXT)) {
|
||||
error++;
|
||||
}
|
||||
if ((cmd->convert_src == TRIG_TIMER) &&
|
||||
!((cmd->scan_begin_src == TRIG_TIMER) ||
|
||||
(cmd->scan_begin_src == TRIG_FOLLOW))) {
|
||||
!((cmd->scan_begin_src == TRIG_TIMER) ||
|
||||
(cmd->scan_begin_src == TRIG_FOLLOW))) {
|
||||
error++;
|
||||
}
|
||||
if ((cmd->convert_src == TRIG_EXT) &&
|
||||
!((cmd->scan_begin_src == TRIG_EXT) ||
|
||||
(cmd->scan_begin_src == TRIG_FOLLOW))) {
|
||||
!((cmd->scan_begin_src == TRIG_EXT) ||
|
||||
(cmd->scan_begin_src == TRIG_FOLLOW))) {
|
||||
error++;
|
||||
}
|
||||
|
||||
@@ -613,7 +625,7 @@ pci9111_ai_do_cmd_test(struct comedi_device *dev,
|
||||
}
|
||||
|
||||
if ((cmd->convert_src == TRIG_TIMER) &&
|
||||
(cmd->convert_arg < board->ai_acquisition_period_min_ns)) {
|
||||
(cmd->convert_arg < board->ai_acquisition_period_min_ns)) {
|
||||
cmd->convert_arg = board->ai_acquisition_period_min_ns;
|
||||
error++;
|
||||
}
|
||||
@@ -623,7 +635,7 @@ pci9111_ai_do_cmd_test(struct comedi_device *dev,
|
||||
}
|
||||
|
||||
if ((cmd->scan_begin_src == TRIG_TIMER) &&
|
||||
(cmd->scan_begin_arg < board->ai_acquisition_period_min_ns)) {
|
||||
(cmd->scan_begin_arg < board->ai_acquisition_period_min_ns)) {
|
||||
cmd->scan_begin_arg = board->ai_acquisition_period_min_ns;
|
||||
error++;
|
||||
}
|
||||
@@ -637,7 +649,7 @@ pci9111_ai_do_cmd_test(struct comedi_device *dev,
|
||||
}
|
||||
|
||||
if ((cmd->scan_end_src == TRIG_COUNT) &&
|
||||
(cmd->scan_end_arg != cmd->chanlist_len)) {
|
||||
(cmd->scan_end_arg != cmd->chanlist_len)) {
|
||||
cmd->scan_end_arg = cmd->chanlist_len;
|
||||
error++;
|
||||
}
|
||||
@@ -659,9 +671,10 @@ pci9111_ai_do_cmd_test(struct comedi_device *dev,
|
||||
if (cmd->convert_src == TRIG_TIMER) {
|
||||
tmp = cmd->convert_arg;
|
||||
i8253_cascade_ns_to_timer_2div(PCI9111_8254_CLOCK_PERIOD_NS,
|
||||
&(dev_private->timer_divisor_1),
|
||||
&(dev_private->timer_divisor_2),
|
||||
&(cmd->convert_arg), cmd->flags & TRIG_ROUND_MASK);
|
||||
&(dev_private->timer_divisor_1),
|
||||
&(dev_private->timer_divisor_2),
|
||||
&(cmd->convert_arg),
|
||||
cmd->flags & TRIG_ROUND_MASK);
|
||||
if (tmp != cmd->convert_arg)
|
||||
error++;
|
||||
}
|
||||
@@ -679,7 +692,7 @@ pci9111_ai_do_cmd_test(struct comedi_device *dev,
|
||||
if (cmd->scan_begin_arg != scan_begin_min) {
|
||||
if (scan_begin_min < cmd->scan_begin_arg) {
|
||||
scan_factor =
|
||||
cmd->scan_begin_arg / scan_begin_min;
|
||||
cmd->scan_begin_arg / scan_begin_min;
|
||||
scan_begin_arg = scan_factor * scan_begin_min;
|
||||
if (cmd->scan_begin_arg != scan_begin_arg) {
|
||||
cmd->scan_begin_arg = scan_begin_arg;
|
||||
@@ -706,27 +719,27 @@ pci9111_ai_do_cmd_test(struct comedi_device *dev,
|
||||
for (i = 0; i < cmd->chanlist_len; i++) {
|
||||
if (CR_CHAN(cmd->chanlist[i]) != i) {
|
||||
comedi_error(dev,
|
||||
"entries in chanlist must be consecutive "
|
||||
"channels,counting upwards from 0\n");
|
||||
"entries in chanlist must be consecutive "
|
||||
"channels,counting upwards from 0\n");
|
||||
error++;
|
||||
}
|
||||
if (CR_RANGE(cmd->chanlist[i]) != range) {
|
||||
comedi_error(dev,
|
||||
"entries in chanlist must all have the same gain\n");
|
||||
"entries in chanlist must all have the same gain\n");
|
||||
error++;
|
||||
}
|
||||
if (CR_AREF(cmd->chanlist[i]) != reference) {
|
||||
comedi_error(dev,
|
||||
"entries in chanlist must all have the same reference\n");
|
||||
"entries in chanlist must all have the same reference\n");
|
||||
error++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ((CR_CHAN(cmd->chanlist[0]) >
|
||||
(board->ai_channel_nbr - 1))
|
||||
|| (CR_CHAN(cmd->chanlist[0]) < 0)) {
|
||||
(board->ai_channel_nbr - 1))
|
||||
|| (CR_CHAN(cmd->chanlist[0]) < 0)) {
|
||||
comedi_error(dev,
|
||||
"channel number is out of limits\n");
|
||||
"channel number is out of limits\n");
|
||||
error++;
|
||||
}
|
||||
}
|
||||
@@ -741,13 +754,14 @@ pci9111_ai_do_cmd_test(struct comedi_device *dev,
|
||||
|
||||
/* Analog input command */
|
||||
|
||||
static int pci9111_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *subdevice)
|
||||
static int pci9111_ai_do_cmd(struct comedi_device *dev,
|
||||
struct comedi_subdevice *subdevice)
|
||||
{
|
||||
struct comedi_cmd *async_cmd = &subdevice->async->cmd;
|
||||
|
||||
if (!dev->irq) {
|
||||
comedi_error(dev,
|
||||
"no irq assigned for PCI9111, cannot do hardware conversion");
|
||||
"no irq assigned for PCI9111, cannot do hardware conversion");
|
||||
return -1;
|
||||
}
|
||||
/* Set channel scan limit */
|
||||
@@ -772,7 +786,7 @@ static int pci9111_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice
|
||||
switch (async_cmd->stop_src) {
|
||||
case TRIG_COUNT:
|
||||
dev_private->stop_counter =
|
||||
async_cmd->stop_arg * async_cmd->chanlist_len;
|
||||
async_cmd->stop_arg * async_cmd->chanlist_len;
|
||||
dev_private->stop_is_none = 0;
|
||||
break;
|
||||
|
||||
@@ -792,28 +806,29 @@ static int pci9111_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice
|
||||
switch (async_cmd->convert_src) {
|
||||
case TRIG_TIMER:
|
||||
i8253_cascade_ns_to_timer_2div(PCI9111_8254_CLOCK_PERIOD_NS,
|
||||
&(dev_private->timer_divisor_1),
|
||||
&(dev_private->timer_divisor_2),
|
||||
&(async_cmd->convert_arg),
|
||||
async_cmd->flags & TRIG_ROUND_MASK);
|
||||
&(dev_private->timer_divisor_1),
|
||||
&(dev_private->timer_divisor_2),
|
||||
&(async_cmd->convert_arg),
|
||||
async_cmd->
|
||||
flags & TRIG_ROUND_MASK);
|
||||
#ifdef AI_DO_CMD_DEBUG
|
||||
printk(PCI9111_DRIVER_NAME ": divisors = %d, %d\n",
|
||||
dev_private->timer_divisor_1,
|
||||
dev_private->timer_divisor_2);
|
||||
dev_private->timer_divisor_1,
|
||||
dev_private->timer_divisor_2);
|
||||
#endif
|
||||
|
||||
pci9111_trigger_source_set(dev, software);
|
||||
pci9111_timer_set(dev);
|
||||
pci9111_fifo_reset();
|
||||
pci9111_interrupt_source_set(dev, irq_on_fifo_half_full,
|
||||
irq_on_timer_tick);
|
||||
irq_on_timer_tick);
|
||||
pci9111_trigger_source_set(dev, timer_pacer);
|
||||
plx9050_interrupt_control(dev_private->lcr_io_base, true, true,
|
||||
false, true, true);
|
||||
false, true, true);
|
||||
|
||||
dev_private->scan_delay =
|
||||
(async_cmd->scan_begin_arg / (async_cmd->convert_arg *
|
||||
async_cmd->chanlist_len)) - 1;
|
||||
(async_cmd->scan_begin_arg / (async_cmd->convert_arg *
|
||||
async_cmd->chanlist_len)) - 1;
|
||||
|
||||
break;
|
||||
|
||||
@@ -822,9 +837,9 @@ static int pci9111_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice
|
||||
pci9111_trigger_source_set(dev, external);
|
||||
pci9111_fifo_reset();
|
||||
pci9111_interrupt_source_set(dev, irq_on_fifo_half_full,
|
||||
irq_on_timer_tick);
|
||||
irq_on_timer_tick);
|
||||
plx9050_interrupt_control(dev_private->lcr_io_base, true, true,
|
||||
false, true, true);
|
||||
false, true, true);
|
||||
|
||||
break;
|
||||
|
||||
@@ -837,45 +852,47 @@ static int pci9111_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice
|
||||
dev_private->chanlist_len = async_cmd->chanlist_len;
|
||||
dev_private->chunk_counter = 0;
|
||||
dev_private->chunk_num_samples =
|
||||
dev_private->chanlist_len * (1 + dev_private->scan_delay);
|
||||
dev_private->chanlist_len * (1 + dev_private->scan_delay);
|
||||
|
||||
#ifdef AI_DO_CMD_DEBUG
|
||||
printk(PCI9111_DRIVER_NAME ": start interruptions!\n");
|
||||
printk(PCI9111_DRIVER_NAME ": trigger source = %2x\n",
|
||||
pci9111_trigger_and_autoscan_get());
|
||||
pci9111_trigger_and_autoscan_get());
|
||||
printk(PCI9111_DRIVER_NAME ": irq source = %2x\n",
|
||||
pci9111_interrupt_and_fifo_get());
|
||||
pci9111_interrupt_and_fifo_get());
|
||||
printk(PCI9111_DRIVER_NAME ": ai_do_cmd\n");
|
||||
printk(PCI9111_DRIVER_NAME ": stop counter = %d\n",
|
||||
dev_private->stop_counter);
|
||||
dev_private->stop_counter);
|
||||
printk(PCI9111_DRIVER_NAME ": scan delay = %d\n",
|
||||
dev_private->scan_delay);
|
||||
dev_private->scan_delay);
|
||||
printk(PCI9111_DRIVER_NAME ": chanlist_len = %d\n",
|
||||
dev_private->chanlist_len);
|
||||
dev_private->chanlist_len);
|
||||
printk(PCI9111_DRIVER_NAME ": chunk num samples = %d\n",
|
||||
dev_private->chunk_num_samples);
|
||||
dev_private->chunk_num_samples);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pci9111_ai_munge(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
void *data, unsigned int num_bytes, unsigned int start_chan_index)
|
||||
static void pci9111_ai_munge(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, void *data,
|
||||
unsigned int num_bytes,
|
||||
unsigned int start_chan_index)
|
||||
{
|
||||
unsigned int i, num_samples = num_bytes / sizeof(short);
|
||||
short *array = data;
|
||||
int resolution =
|
||||
((struct pci9111_board *) dev->board_ptr)->ai_resolution;
|
||||
((struct pci9111_board *)dev->board_ptr)->ai_resolution;
|
||||
|
||||
for (i = 0; i < num_samples; i++) {
|
||||
if (resolution == PCI9111_HR_AI_RESOLUTION)
|
||||
array[i] =
|
||||
(array[i] & PCI9111_HR_AI_RESOLUTION_MASK) ^
|
||||
PCI9111_HR_AI_RESOLUTION_2_CMP_BIT;
|
||||
(array[i] & PCI9111_HR_AI_RESOLUTION_MASK) ^
|
||||
PCI9111_HR_AI_RESOLUTION_2_CMP_BIT;
|
||||
else
|
||||
array[i] =
|
||||
((array[i] >> 4) & PCI9111_AI_RESOLUTION_MASK) ^
|
||||
PCI9111_AI_RESOLUTION_2_CMP_BIT;
|
||||
((array[i] >> 4) & PCI9111_AI_RESOLUTION_MASK) ^
|
||||
PCI9111_AI_RESOLUTION_2_CMP_BIT;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -905,18 +922,12 @@ static irqreturn_t pci9111_interrupt(int irq, void *p_device)
|
||||
|
||||
/* Check if we are source of interrupt */
|
||||
intcsr = inb(dev_private->lcr_io_base +
|
||||
PLX9050_REGISTER_INTERRUPT_CONTROL);
|
||||
PLX9050_REGISTER_INTERRUPT_CONTROL);
|
||||
if (!(((intcsr & PLX9050_PCI_INTERRUPT_ENABLE) != 0)
|
||||
&& (((intcsr & (PLX9050_LINTI1_ENABLE |
|
||||
PLX9050_LINTI1_STATUS))
|
||||
==
|
||||
(PLX9050_LINTI1_ENABLE |
|
||||
PLX9050_LINTI1_STATUS))
|
||||
|| ((intcsr & (PLX9050_LINTI2_ENABLE |
|
||||
PLX9050_LINTI2_STATUS))
|
||||
==
|
||||
(PLX9050_LINTI2_ENABLE |
|
||||
PLX9050_LINTI2_STATUS))))) {
|
||||
&& (((intcsr & (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS))
|
||||
== (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS))
|
||||
|| ((intcsr & (PLX9050_LINTI2_ENABLE | PLX9050_LINTI2_STATUS))
|
||||
== (PLX9050_LINTI2_ENABLE | PLX9050_LINTI2_STATUS))))) {
|
||||
/* Not the source of the interrupt. */
|
||||
/* (N.B. not using PLX9050_SOFTWARE_INTERRUPT) */
|
||||
spin_unlock_irqrestore(&dev->spinlock, irq_flags);
|
||||
@@ -924,12 +935,11 @@ static irqreturn_t pci9111_interrupt(int irq, void *p_device)
|
||||
}
|
||||
|
||||
if ((intcsr & (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) ==
|
||||
(PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) {
|
||||
(PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) {
|
||||
/* Interrupt comes from fifo_half-full signal */
|
||||
|
||||
if (pci9111_is_fifo_full()) {
|
||||
spin_unlock_irqrestore(&dev->spinlock,
|
||||
irq_flags);
|
||||
spin_unlock_irqrestore(&dev->spinlock, irq_flags);
|
||||
comedi_error(dev, PCI9111_DRIVER_NAME " fifo overflow");
|
||||
pci9111_interrupt_clear();
|
||||
pci9111_ai_cancel(dev, subdevice);
|
||||
@@ -948,73 +958,70 @@ static irqreturn_t pci9111_interrupt(int irq, void *p_device)
|
||||
#endif
|
||||
|
||||
num_samples =
|
||||
PCI9111_FIFO_HALF_SIZE >
|
||||
dev_private->stop_counter
|
||||
&& !dev_private->stop_is_none ? dev_private->
|
||||
stop_counter : PCI9111_FIFO_HALF_SIZE;
|
||||
PCI9111_FIFO_HALF_SIZE >
|
||||
dev_private->stop_counter
|
||||
&& !dev_private->
|
||||
stop_is_none ? dev_private->stop_counter :
|
||||
PCI9111_FIFO_HALF_SIZE;
|
||||
insw(PCI9111_IO_BASE + PCI9111_REGISTER_AD_FIFO_VALUE,
|
||||
dev_private->ai_bounce_buffer, num_samples);
|
||||
dev_private->ai_bounce_buffer, num_samples);
|
||||
|
||||
if (dev_private->scan_delay < 1) {
|
||||
bytes_written =
|
||||
cfc_write_array_to_buffer(subdevice,
|
||||
dev_private->ai_bounce_buffer,
|
||||
num_samples * sizeof(short));
|
||||
cfc_write_array_to_buffer(subdevice,
|
||||
dev_private->
|
||||
ai_bounce_buffer,
|
||||
num_samples *
|
||||
sizeof(short));
|
||||
} else {
|
||||
int position = 0;
|
||||
int to_read;
|
||||
|
||||
while (position < num_samples) {
|
||||
if (dev_private->chunk_counter <
|
||||
dev_private->chanlist_len) {
|
||||
dev_private->chanlist_len) {
|
||||
to_read =
|
||||
dev_private->
|
||||
chanlist_len -
|
||||
dev_private->
|
||||
chunk_counter;
|
||||
dev_private->chanlist_len -
|
||||
dev_private->chunk_counter;
|
||||
|
||||
if (to_read >
|
||||
num_samples - position)
|
||||
num_samples - position)
|
||||
to_read =
|
||||
num_samples -
|
||||
position;
|
||||
num_samples -
|
||||
position;
|
||||
|
||||
bytes_written +=
|
||||
cfc_write_array_to_buffer
|
||||
(subdevice,
|
||||
dev_private->
|
||||
ai_bounce_buffer +
|
||||
position,
|
||||
to_read *
|
||||
sizeof(short));
|
||||
cfc_write_array_to_buffer
|
||||
(subdevice,
|
||||
dev_private->ai_bounce_buffer
|
||||
+ position,
|
||||
to_read * sizeof(short));
|
||||
} else {
|
||||
to_read =
|
||||
dev_private->
|
||||
chunk_num_samples -
|
||||
dev_private->
|
||||
chunk_counter;
|
||||
dev_private->chunk_num_samples
|
||||
-
|
||||
dev_private->chunk_counter;
|
||||
if (to_read >
|
||||
num_samples - position)
|
||||
num_samples - position)
|
||||
to_read =
|
||||
num_samples -
|
||||
position;
|
||||
num_samples -
|
||||
position;
|
||||
|
||||
bytes_written +=
|
||||
sizeof(short) *
|
||||
to_read;
|
||||
sizeof(short) * to_read;
|
||||
}
|
||||
|
||||
position += to_read;
|
||||
dev_private->chunk_counter += to_read;
|
||||
|
||||
if (dev_private->chunk_counter >=
|
||||
dev_private->chunk_num_samples)
|
||||
dev_private->chunk_num_samples)
|
||||
dev_private->chunk_counter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
dev_private->stop_counter -=
|
||||
bytes_written / sizeof(short);
|
||||
bytes_written / sizeof(short);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1044,17 +1051,18 @@ static irqreturn_t pci9111_interrupt(int irq, void *p_device)
|
||||
#undef AI_INSN_DEBUG
|
||||
|
||||
static int pci9111_ai_insn_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *subdevice, struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_subdevice *subdevice,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int resolution =
|
||||
((struct pci9111_board *) dev->board_ptr)->ai_resolution;
|
||||
((struct pci9111_board *)dev->board_ptr)->ai_resolution;
|
||||
|
||||
int timeout, i;
|
||||
|
||||
#ifdef AI_INSN_DEBUG
|
||||
printk(PCI9111_DRIVER_NAME ": ai_insn set c/r/n = %2x/%2x/%2x\n",
|
||||
CR_CHAN((&insn->chanspec)[0]),
|
||||
CR_RANGE((&insn->chanspec)[0]), insn->n);
|
||||
CR_CHAN((&insn->chanspec)[0]),
|
||||
CR_RANGE((&insn->chanspec)[0]), insn->n);
|
||||
#endif
|
||||
|
||||
pci9111_ai_channel_set(CR_CHAN((&insn->chanspec)[0]));
|
||||
@@ -1080,7 +1088,7 @@ static int pci9111_ai_insn_read(struct comedi_device *dev,
|
||||
pci9111_fifo_reset();
|
||||
return -ETIME;
|
||||
|
||||
conversion_done:
|
||||
conversion_done:
|
||||
|
||||
if (resolution == PCI9111_HR_AI_RESOLUTION) {
|
||||
data[i] = pci9111_hr_ai_get_data();
|
||||
@@ -1091,8 +1099,8 @@ static int pci9111_ai_insn_read(struct comedi_device *dev,
|
||||
|
||||
#ifdef AI_INSN_DEBUG
|
||||
printk(PCI9111_DRIVER_NAME ": ai_insn get c/r/t = %2x/%2x/%2x\n",
|
||||
pci9111_ai_channel_get(),
|
||||
pci9111_ai_range_get(), pci9111_trigger_and_autoscan_get());
|
||||
pci9111_ai_channel_get(),
|
||||
pci9111_ai_range_get(), pci9111_trigger_and_autoscan_get());
|
||||
#endif
|
||||
|
||||
return i;
|
||||
@@ -1102,7 +1110,8 @@ static int pci9111_ai_insn_read(struct comedi_device *dev,
|
||||
|
||||
static int
|
||||
pci9111_ao_insn_write(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -1117,7 +1126,8 @@ pci9111_ao_insn_write(struct comedi_device *dev,
|
||||
/* Analog output readback */
|
||||
|
||||
static int pci9111_ao_insn_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -1135,7 +1145,8 @@ static int pci9111_ao_insn_read(struct comedi_device *dev,
|
||||
/* Digital inputs */
|
||||
|
||||
static int pci9111_di_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *subdevice, struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_subdevice *subdevice,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
unsigned int bits;
|
||||
|
||||
@@ -1148,7 +1159,8 @@ static int pci9111_di_insn_bits(struct comedi_device *dev,
|
||||
/* Digital outputs */
|
||||
|
||||
static int pci9111_do_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *subdevice, struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_subdevice *subdevice,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
unsigned int bits;
|
||||
|
||||
@@ -1181,7 +1193,7 @@ static int pci9111_reset(struct comedi_device *dev)
|
||||
/* Set trigger source to software */
|
||||
|
||||
plx9050_interrupt_control(dev_private->lcr_io_base, true, true, true,
|
||||
true, false);
|
||||
true, false);
|
||||
|
||||
pci9111_trigger_source_set(dev, software);
|
||||
pci9111_pretrigger_set(dev, false);
|
||||
@@ -1201,7 +1213,8 @@ static int pci9111_reset(struct comedi_device *dev)
|
||||
/* - Register PCI device */
|
||||
/* - Declare device driver capability */
|
||||
|
||||
static int pci9111_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
static int pci9111_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it)
|
||||
{
|
||||
struct comedi_subdevice *subdevice;
|
||||
unsigned long io_base, io_range, lcr_io_base, lcr_io_range;
|
||||
@@ -1217,29 +1230,29 @@ static int pci9111_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
printk("comedi%d: " PCI9111_DRIVER_NAME " driver\n", dev->minor);
|
||||
|
||||
for (pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
|
||||
pci_device != NULL;
|
||||
pci_device =
|
||||
pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_device)) {
|
||||
pci_device != NULL;
|
||||
pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_device)) {
|
||||
if (pci_device->vendor == PCI_VENDOR_ID_ADLINK) {
|
||||
for (i = 0; i < pci9111_board_nbr; i++) {
|
||||
if (pci9111_boards[i].device_id ==
|
||||
pci_device->device) {
|
||||
pci_device->device) {
|
||||
/* was a particular bus/slot requested? */
|
||||
if ((it->options[0] != 0)
|
||||
|| (it->options[1] != 0)) {
|
||||
|| (it->options[1] != 0)) {
|
||||
/* are we on the wrong bus/slot? */
|
||||
if (pci_device->bus->number !=
|
||||
it->options[0]
|
||||
|| PCI_SLOT(pci_device->
|
||||
devfn) !=
|
||||
it->options[1]) {
|
||||
it->options[0]
|
||||
||
|
||||
PCI_SLOT(pci_device->devfn)
|
||||
!= it->options[1]) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
dev->board_ptr = pci9111_boards + i;
|
||||
board = (struct pci9111_board *) dev->
|
||||
board_ptr;
|
||||
board =
|
||||
(struct pci9111_board *)
|
||||
dev->board_ptr;
|
||||
dev_private->pci_device = pci_device;
|
||||
goto found;
|
||||
}
|
||||
@@ -1248,17 +1261,17 @@ static int pci9111_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
}
|
||||
|
||||
printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
|
||||
dev->minor, it->options[0], it->options[1]);
|
||||
dev->minor, it->options[0], it->options[1]);
|
||||
return -EIO;
|
||||
|
||||
found:
|
||||
found:
|
||||
|
||||
printk("comedi%d: found %s (b:s:f=%d:%d:%d) , irq=%d\n",
|
||||
dev->minor,
|
||||
pci9111_boards[i].name,
|
||||
pci_device->bus->number,
|
||||
PCI_SLOT(pci_device->devfn),
|
||||
PCI_FUNC(pci_device->devfn), pci_device->irq);
|
||||
dev->minor,
|
||||
pci9111_boards[i].name,
|
||||
pci_device->bus->number,
|
||||
PCI_SLOT(pci_device->devfn),
|
||||
PCI_FUNC(pci_device->devfn), pci_device->irq);
|
||||
|
||||
/* TODO: Warn about non-tested boards. */
|
||||
|
||||
@@ -1270,11 +1283,15 @@ static int pci9111_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
lcr_io_base = pci_resource_start(pci_device, 1);
|
||||
lcr_io_range = pci_resource_len(pci_device, 1);
|
||||
|
||||
printk("comedi%d: local configuration registers at address 0x%4lx [0x%4lx]\n", dev->minor, lcr_io_base, lcr_io_range);
|
||||
printk
|
||||
("comedi%d: local configuration registers at address 0x%4lx [0x%4lx]\n",
|
||||
dev->minor, lcr_io_base, lcr_io_range);
|
||||
|
||||
/* Enable PCI device and request regions */
|
||||
if (comedi_pci_enable(pci_device, PCI9111_DRIVER_NAME) < 0) {
|
||||
printk("comedi%d: Failed to enable PCI device and request regions\n", dev->minor);
|
||||
printk
|
||||
("comedi%d: Failed to enable PCI device and request regions\n",
|
||||
dev->minor);
|
||||
return -EIO;
|
||||
}
|
||||
/* Read PCI6308 register base address [PCI_BASE_ADDRESS #2]. */
|
||||
@@ -1283,7 +1300,7 @@ static int pci9111_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
io_range = pci_resource_len(pci_device, 2);
|
||||
|
||||
printk("comedi%d: 6503 registers at address 0x%4lx [0x%4lx]\n",
|
||||
dev->minor, io_base, io_range);
|
||||
dev->minor, io_base, io_range);
|
||||
|
||||
dev->iobase = io_base;
|
||||
dev->board_name = board->name;
|
||||
@@ -1301,7 +1318,7 @@ static int pci9111_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
if (request_irq(pci_device->irq, pci9111_interrupt,
|
||||
IRQF_SHARED, PCI9111_DRIVER_NAME, dev) != 0) {
|
||||
printk("comedi%d: unable to allocate irq %u\n",
|
||||
dev->minor, pci_device->irq);
|
||||
dev->minor, pci_device->irq);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -62,7 +62,6 @@ If you do not specify any options, they will default to
|
||||
single-ended 0 1-2 1-2 (factory default)
|
||||
differential 1 2-3 2-3
|
||||
|
||||
|
||||
written by jeremy theler <thelerg@ib.cnea.gov.ar>
|
||||
|
||||
instituto balseiro
|
||||
@@ -101,39 +100,39 @@ If you do not specify any options, they will default to
|
||||
|
||||
/* available ranges through the PGA gains */
|
||||
static const struct comedi_lrange range_adq12b_ai_bipolar = { 4, {
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(2),
|
||||
BIP_RANGE(1),
|
||||
BIP_RANGE(0.5)
|
||||
}};
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(2),
|
||||
BIP_RANGE(1),
|
||||
BIP_RANGE(0.5)
|
||||
}
|
||||
};
|
||||
|
||||
static const struct comedi_lrange range_adq12b_ai_unipolar = { 4, {
|
||||
UNI_RANGE(5),
|
||||
UNI_RANGE(2),
|
||||
UNI_RANGE(1),
|
||||
UNI_RANGE(0.5)
|
||||
}};
|
||||
|
||||
|
||||
UNI_RANGE(5),
|
||||
UNI_RANGE(2),
|
||||
UNI_RANGE(1),
|
||||
UNI_RANGE
|
||||
(0.5)
|
||||
}
|
||||
};
|
||||
|
||||
struct adq12b_board {
|
||||
const char *name;
|
||||
int ai_se_chans;
|
||||
int ai_diff_chans;
|
||||
int ai_bits;
|
||||
int di_chans;
|
||||
int do_chans;
|
||||
const char *name;
|
||||
int ai_se_chans;
|
||||
int ai_diff_chans;
|
||||
int ai_bits;
|
||||
int di_chans;
|
||||
int do_chans;
|
||||
};
|
||||
|
||||
static const struct adq12b_board adq12b_boards[] = {
|
||||
{
|
||||
.name = "adq12b",
|
||||
.ai_se_chans = 16,
|
||||
.ai_diff_chans = 8,
|
||||
.ai_bits = 12,
|
||||
.di_chans = 5,
|
||||
.do_chans = 8
|
||||
}
|
||||
{
|
||||
.name = "adq12b",
|
||||
.ai_se_chans = 16,
|
||||
.ai_diff_chans = 8,
|
||||
.ai_bits = 12,
|
||||
.di_chans = 5,
|
||||
.do_chans = 8}
|
||||
/* potentially, more adq-based deviced will be added */
|
||||
/*,
|
||||
.name = "adq12b",
|
||||
@@ -147,11 +146,11 @@ static const struct adq12b_board adq12b_boards[] = {
|
||||
#define thisboard ((const struct adq12b_board *)dev->board_ptr)
|
||||
|
||||
struct adq12b_private {
|
||||
int unipolar; /* option 2 of comedi_config (1 is iobase) */
|
||||
int differential; /* option 3 of comedi_config */
|
||||
int last_channel;
|
||||
int last_range;
|
||||
unsigned int digital_state;
|
||||
int unipolar; /* option 2 of comedi_config (1 is iobase) */
|
||||
int differential; /* option 3 of comedi_config */
|
||||
int last_channel;
|
||||
int last_range;
|
||||
unsigned int digital_state;
|
||||
};
|
||||
|
||||
#define devpriv ((struct adq12b_private *)dev->private)
|
||||
@@ -162,21 +161,28 @@ struct adq12b_private {
|
||||
* the board, and also about the kernel module that contains
|
||||
* the device code.
|
||||
*/
|
||||
static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int adq12b_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int adq12b_detach(struct comedi_device *dev);
|
||||
static struct comedi_driver driver_adq12b={
|
||||
driver_name: "adq12b",
|
||||
module: THIS_MODULE,
|
||||
attach: adq12b_attach,
|
||||
detach: adq12b_detach,
|
||||
board_name: &adq12b_boards[0].name,
|
||||
offset: sizeof(struct adq12b_board),
|
||||
num_names: ARRAY_SIZE(adq12b_boards),
|
||||
static struct comedi_driver driver_adq12b = {
|
||||
driver_name:"adq12b",
|
||||
module:THIS_MODULE,
|
||||
attach:adq12b_attach,
|
||||
detach:adq12b_detach,
|
||||
board_name:&adq12b_boards[0].name,
|
||||
offset:sizeof(struct adq12b_board),
|
||||
num_names:ARRAY_SIZE(adq12b_boards),
|
||||
};
|
||||
|
||||
static int adq12b_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
|
||||
static int adq12b_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
|
||||
static int adq12b_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
|
||||
static int adq12b_ai_rinsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
static int adq12b_di_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int adq12b_do_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
/*
|
||||
* Attach is called by the Comedi core to configure the driver
|
||||
@@ -186,109 +192,108 @@ static int adq12b_do_insn_bits(struct comedi_device *dev, struct comedi_subdevic
|
||||
*/
|
||||
static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
{
|
||||
struct comedi_subdevice *s;
|
||||
unsigned long iobase;
|
||||
int unipolar, differential;
|
||||
struct comedi_subdevice *s;
|
||||
unsigned long iobase;
|
||||
int unipolar, differential;
|
||||
|
||||
iobase = it->options[0];
|
||||
unipolar = it->options[1];
|
||||
differential = it->options[2];
|
||||
iobase = it->options[0];
|
||||
unipolar = it->options[1];
|
||||
differential = it->options[2];
|
||||
|
||||
printk("comedi%d: adq12b called with options base=0x%03lx, %s and %s\n", dev->minor, iobase, (unipolar==1)?"unipolar":"bipolar", (differential==1) ? "differential" : "single-ended");
|
||||
printk("comedi%d: adq12b called with options base=0x%03lx, %s and %s\n",
|
||||
dev->minor, iobase, (unipolar == 1) ? "unipolar" : "bipolar",
|
||||
(differential == 1) ? "differential" : "single-ended");
|
||||
|
||||
/* if no address was specified, try the default 0x300 */
|
||||
if (iobase == 0) {
|
||||
printk("comedi%d: adq12b warning: I/O base address not specified. Trying the default 0x300.\n", dev->minor);
|
||||
iobase = 0x300;
|
||||
}
|
||||
/* if no address was specified, try the default 0x300 */
|
||||
if (iobase == 0) {
|
||||
printk
|
||||
("comedi%d: adq12b warning: I/O base address not specified. Trying the default 0x300.\n",
|
||||
dev->minor);
|
||||
iobase = 0x300;
|
||||
}
|
||||
|
||||
printk("comedi%d: adq12b: 0x%04lx ", dev->minor, iobase);
|
||||
if (!request_region(iobase, ADQ12B_SIZE, "adq12b")) {
|
||||
printk("I/O port conflict\n");
|
||||
return -EIO;
|
||||
}
|
||||
dev->iobase = iobase;
|
||||
printk("comedi%d: adq12b: 0x%04lx ", dev->minor, iobase);
|
||||
if (!request_region(iobase, ADQ12B_SIZE, "adq12b")) {
|
||||
printk("I/O port conflict\n");
|
||||
return -EIO;
|
||||
}
|
||||
dev->iobase = iobase;
|
||||
|
||||
/*
|
||||
* Initialize dev->board_name. Note that we can use the "thisboard"
|
||||
* macro now, since we just initialized it in the last line.
|
||||
*/
|
||||
dev->board_name = thisboard->name;
|
||||
dev->board_name = thisboard->name;
|
||||
|
||||
/*
|
||||
* Allocate the private structure area. alloc_private() is a
|
||||
* convenient macro defined in comedidev.h.
|
||||
*/
|
||||
if (alloc_private (dev, sizeof (struct adq12b_private)) < 0)
|
||||
return -ENOMEM;
|
||||
if (alloc_private(dev, sizeof(struct adq12b_private)) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
/* fill in devpriv structure */
|
||||
devpriv->unipolar = unipolar;
|
||||
devpriv->differential = differential;
|
||||
devpriv->unipolar = unipolar;
|
||||
devpriv->differential = differential;
|
||||
devpriv->digital_state = 0;
|
||||
/* initialize channel and range to -1 so we make sure we always write
|
||||
at least once to the CTREG in the instruction */
|
||||
devpriv->last_channel = -1;
|
||||
devpriv->last_range = -1;
|
||||
|
||||
devpriv->last_channel = -1;
|
||||
devpriv->last_range = -1;
|
||||
|
||||
/*
|
||||
* Allocate the subdevice structures. alloc_subdevice() is a
|
||||
* convenient macro defined in comedidev.h.
|
||||
*/
|
||||
if (alloc_subdevices (dev, 3)<0)
|
||||
return -ENOMEM;
|
||||
if (alloc_subdevices(dev, 3) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
s = dev->subdevices+0;
|
||||
/* analog input subdevice */
|
||||
s->type = COMEDI_SUBD_AI;
|
||||
if (differential) {
|
||||
s->subdev_flags = SDF_READABLE|SDF_GROUND|SDF_DIFF;
|
||||
s->n_chan = thisboard->ai_diff_chans;
|
||||
} else {
|
||||
s->subdev_flags = SDF_READABLE|SDF_GROUND;
|
||||
s->n_chan = thisboard->ai_se_chans;
|
||||
}
|
||||
s = dev->subdevices + 0;
|
||||
/* analog input subdevice */
|
||||
s->type = COMEDI_SUBD_AI;
|
||||
if (differential) {
|
||||
s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF;
|
||||
s->n_chan = thisboard->ai_diff_chans;
|
||||
} else {
|
||||
s->subdev_flags = SDF_READABLE | SDF_GROUND;
|
||||
s->n_chan = thisboard->ai_se_chans;
|
||||
}
|
||||
|
||||
if (unipolar) {
|
||||
s->range_table = &range_adq12b_ai_unipolar;
|
||||
} else {
|
||||
s->range_table = &range_adq12b_ai_bipolar;
|
||||
}
|
||||
if (unipolar) {
|
||||
s->range_table = &range_adq12b_ai_unipolar;
|
||||
} else {
|
||||
s->range_table = &range_adq12b_ai_bipolar;
|
||||
}
|
||||
|
||||
s->maxdata = (1 << thisboard->ai_bits)-1;
|
||||
s->maxdata = (1 << thisboard->ai_bits) - 1;
|
||||
|
||||
s->len_chanlist = 4; /* This is the maximum chanlist length that
|
||||
the board can handle */
|
||||
s->insn_read = adq12b_ai_rinsn;
|
||||
|
||||
s->len_chanlist = 4; /* This is the maximum chanlist length that
|
||||
the board can handle */
|
||||
s->insn_read = adq12b_ai_rinsn;
|
||||
s = dev->subdevices + 1;
|
||||
/* digital input subdevice */
|
||||
s->type = COMEDI_SUBD_DI;
|
||||
s->subdev_flags = SDF_READABLE;
|
||||
s->n_chan = thisboard->di_chans;
|
||||
s->maxdata = 1;
|
||||
s->range_table = &range_digital;
|
||||
s->insn_bits = adq12b_di_insn_bits;
|
||||
|
||||
s = dev->subdevices + 2;
|
||||
/* digital output subdevice */
|
||||
s->type = COMEDI_SUBD_DO;
|
||||
s->subdev_flags = SDF_WRITABLE;
|
||||
s->n_chan = thisboard->do_chans;
|
||||
s->maxdata = 1;
|
||||
s->range_table = &range_digital;
|
||||
s->insn_bits = adq12b_do_insn_bits;
|
||||
|
||||
s = dev->subdevices+1;
|
||||
/* digital input subdevice */
|
||||
s->type = COMEDI_SUBD_DI;
|
||||
s->subdev_flags = SDF_READABLE;
|
||||
s->n_chan=thisboard->di_chans;
|
||||
s->maxdata = 1;
|
||||
s->range_table = &range_digital;
|
||||
s->insn_bits = adq12b_di_insn_bits;
|
||||
printk("attached\n");
|
||||
|
||||
s = dev->subdevices+2;
|
||||
/* digital output subdevice */
|
||||
s->type = COMEDI_SUBD_DO;
|
||||
s->subdev_flags = SDF_WRITABLE;
|
||||
s->n_chan = thisboard->do_chans;
|
||||
s->maxdata = 1;
|
||||
s->range_table = &range_digital;
|
||||
s->insn_bits = adq12b_do_insn_bits;
|
||||
|
||||
|
||||
printk("attached\n");
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* _detach is called to deconfigure a device. It should deallocate
|
||||
* resources.
|
||||
@@ -299,14 +304,14 @@ static int adq12b_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
*/
|
||||
static int adq12b_detach(struct comedi_device *dev)
|
||||
{
|
||||
if (dev->iobase)
|
||||
release_region(dev->iobase, ADQ12B_SIZE);
|
||||
if (dev->iobase)
|
||||
release_region(dev->iobase, ADQ12B_SIZE);
|
||||
|
||||
kfree(devpriv);
|
||||
kfree(devpriv);
|
||||
|
||||
printk("comedi%d: adq12b: removed\n", dev->minor);
|
||||
printk("comedi%d: adq12b: removed\n", dev->minor);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -314,79 +319,83 @@ static int adq12b_detach(struct comedi_device *dev)
|
||||
* mode.
|
||||
*/
|
||||
|
||||
static int adq12b_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
|
||||
static int adq12b_ai_rinsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
int n, i;
|
||||
int range, channel;
|
||||
unsigned char hi, lo, status;
|
||||
int n, i;
|
||||
int range, channel;
|
||||
unsigned char hi, lo, status;
|
||||
|
||||
/* change channel and range only if it is different from the previous */
|
||||
range = CR_RANGE(insn->chanspec);
|
||||
channel = CR_CHAN(insn->chanspec);
|
||||
if (channel != devpriv->last_channel || range != devpriv->last_range) {
|
||||
outb((range << 4) | channel, dev->iobase + ADQ12B_CTREG);
|
||||
udelay(50); /* wait for the mux to settle */
|
||||
}
|
||||
/* change channel and range only if it is different from the previous */
|
||||
range = CR_RANGE(insn->chanspec);
|
||||
channel = CR_CHAN(insn->chanspec);
|
||||
if (channel != devpriv->last_channel || range != devpriv->last_range) {
|
||||
outb((range << 4) | channel, dev->iobase + ADQ12B_CTREG);
|
||||
udelay(50); /* wait for the mux to settle */
|
||||
}
|
||||
|
||||
/* trigger conversion */
|
||||
status = inb(dev->iobase + ADQ12B_ADLOW);
|
||||
/* trigger conversion */
|
||||
status = inb(dev->iobase + ADQ12B_ADLOW);
|
||||
|
||||
/* convert n samples */
|
||||
for (n=0; n < insn->n; n++){
|
||||
/* convert n samples */
|
||||
for (n = 0; n < insn->n; n++) {
|
||||
|
||||
/* wait for end of convertion */
|
||||
i = 0;
|
||||
do {
|
||||
/* wait for end of convertion */
|
||||
i = 0;
|
||||
do {
|
||||
/* udelay(1); */
|
||||
status = inb(dev->iobase + ADQ12B_STINR);
|
||||
status = status & ADQ12B_EOC;
|
||||
} while (status == 0 && ++i < TIMEOUT);
|
||||
status = inb(dev->iobase + ADQ12B_STINR);
|
||||
status = status & ADQ12B_EOC;
|
||||
} while (status == 0 && ++i < TIMEOUT);
|
||||
/* } while (++i < 10); */
|
||||
|
||||
/* read data */
|
||||
hi = inb(dev->iobase + ADQ12B_ADHIG);
|
||||
lo = inb(dev->iobase + ADQ12B_ADLOW);
|
||||
/* read data */
|
||||
hi = inb(dev->iobase + ADQ12B_ADHIG);
|
||||
lo = inb(dev->iobase + ADQ12B_ADLOW);
|
||||
|
||||
/* printk("debug: chan=%d range=%d status=%d hi=%d lo=%d\n", channel, range, status, hi, lo); */
|
||||
data[n] = (hi << 8) | lo;
|
||||
/* printk("debug: chan=%d range=%d status=%d hi=%d lo=%d\n", channel, range, status, hi, lo); */
|
||||
data[n] = (hi << 8) | lo;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* return the number of samples read/written */
|
||||
return n;
|
||||
/* return the number of samples read/written */
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
static int adq12b_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
|
||||
static int adq12b_di_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
|
||||
/* only bits 0-4 have information about digital inputs */
|
||||
data[1] = (inb(dev->iobase+ADQ12B_STINR) & (0x1f));
|
||||
/* only bits 0-4 have information about digital inputs */
|
||||
data[1] = (inb(dev->iobase + ADQ12B_STINR) & (0x1f));
|
||||
|
||||
return 2;
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
static int adq12b_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
|
||||
static int adq12b_do_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int channel;
|
||||
int channel;
|
||||
|
||||
for (channel = 0; channel < 8; channel++)
|
||||
if (((data[0]>>channel) & 0x01) != 0)
|
||||
outb((((data[1]>>channel)&0x01)<<3) | channel, dev->iobase + ADQ12B_OUTBR);
|
||||
if (((data[0] >> channel) & 0x01) != 0)
|
||||
outb((((data[1] >> channel) & 0x01) << 3) | channel,
|
||||
dev->iobase + ADQ12B_OUTBR);
|
||||
|
||||
/* store information to retrieve when asked for reading */
|
||||
if (data[0]) {
|
||||
devpriv->digital_state &= ~data[0];
|
||||
devpriv->digital_state |= (data[0]&data[1]);
|
||||
}
|
||||
/* store information to retrieve when asked for reading */
|
||||
if (data[0]) {
|
||||
devpriv->digital_state &= ~data[0];
|
||||
devpriv->digital_state |= (data[0] & data[1]);
|
||||
}
|
||||
|
||||
data[1] = devpriv->digital_state;
|
||||
data[1] = devpriv->digital_state;
|
||||
|
||||
return 2;
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* A convenient macro that defines init_module() and cleanup_module(),
|
||||
* as necessary.
|
||||
|
||||
@@ -124,67 +124,69 @@ Configuration options:
|
||||
#define Syncont_SC0 1 /* set synchronous output mode */
|
||||
|
||||
static const struct comedi_lrange range_pci1710_3 = { 9, {
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(2.5),
|
||||
BIP_RANGE(1.25),
|
||||
BIP_RANGE(0.625),
|
||||
BIP_RANGE(10),
|
||||
UNI_RANGE(10),
|
||||
UNI_RANGE(5),
|
||||
UNI_RANGE(2.5),
|
||||
UNI_RANGE(1.25)
|
||||
}
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(2.5),
|
||||
BIP_RANGE(1.25),
|
||||
BIP_RANGE(0.625),
|
||||
BIP_RANGE(10),
|
||||
UNI_RANGE(10),
|
||||
UNI_RANGE(5),
|
||||
UNI_RANGE(2.5),
|
||||
UNI_RANGE(1.25)
|
||||
}
|
||||
};
|
||||
|
||||
static const char range_codes_pci1710_3[] =
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x10, 0x11, 0x12, 0x13 };
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x10, 0x11, 0x12, 0x13 };
|
||||
|
||||
static const struct comedi_lrange range_pci1710hg = { 12, {
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(0.5),
|
||||
BIP_RANGE(0.05),
|
||||
BIP_RANGE(0.005),
|
||||
BIP_RANGE(10),
|
||||
BIP_RANGE(1),
|
||||
BIP_RANGE(0.1),
|
||||
BIP_RANGE(0.01),
|
||||
UNI_RANGE(10),
|
||||
UNI_RANGE(1),
|
||||
UNI_RANGE(0.1),
|
||||
UNI_RANGE(0.01)
|
||||
}
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(0.5),
|
||||
BIP_RANGE(0.05),
|
||||
BIP_RANGE(0.005),
|
||||
BIP_RANGE(10),
|
||||
BIP_RANGE(1),
|
||||
BIP_RANGE(0.1),
|
||||
BIP_RANGE(0.01),
|
||||
UNI_RANGE(10),
|
||||
UNI_RANGE(1),
|
||||
UNI_RANGE(0.1),
|
||||
UNI_RANGE(0.01)
|
||||
}
|
||||
};
|
||||
|
||||
static const char range_codes_pci1710hg[] =
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x11, 0x12,
|
||||
0x13 };
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x11, 0x12,
|
||||
0x13
|
||||
};
|
||||
|
||||
static const struct comedi_lrange range_pci17x1 = { 5, {
|
||||
BIP_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(2.5),
|
||||
BIP_RANGE(1.25),
|
||||
BIP_RANGE(0.625)
|
||||
}
|
||||
BIP_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(2.5),
|
||||
BIP_RANGE(1.25),
|
||||
BIP_RANGE(0.625)
|
||||
}
|
||||
};
|
||||
|
||||
static const char range_codes_pci17x1[] = { 0x00, 0x01, 0x02, 0x03, 0x04 };
|
||||
|
||||
static const struct comedi_lrange range_pci1720 = { 4, {
|
||||
UNI_RANGE(5),
|
||||
UNI_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(10)
|
||||
}
|
||||
UNI_RANGE(5),
|
||||
UNI_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(10)
|
||||
}
|
||||
};
|
||||
|
||||
static const struct comedi_lrange range_pci171x_da = { 2, {
|
||||
UNI_RANGE(5),
|
||||
UNI_RANGE(10),
|
||||
}
|
||||
UNI_RANGE(5),
|
||||
UNI_RANGE(10),
|
||||
}
|
||||
};
|
||||
|
||||
static int pci1710_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int pci1710_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int pci1710_detach(struct comedi_device *dev);
|
||||
|
||||
struct boardtype {
|
||||
@@ -209,49 +211,50 @@ struct boardtype {
|
||||
};
|
||||
|
||||
static DEFINE_PCI_DEVICE_TABLE(pci1710_pci_table) = {
|
||||
{PCI_VENDOR_ID_ADVANTECH, 0x1710, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_ADVANTECH, 0x1711, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_ADVANTECH, 0x1713, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_ADVANTECH, 0x1720, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_ADVANTECH, 0x1731, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{0}
|
||||
{
|
||||
PCI_VENDOR_ID_ADVANTECH, 0x1710, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_ADVANTECH, 0x1711, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_ADVANTECH, 0x1713, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_ADVANTECH, 0x1720, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_ADVANTECH, 0x1731, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
0}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, pci1710_pci_table);
|
||||
|
||||
static const struct boardtype boardtypes[] = {
|
||||
{"pci1710", 0x1710,
|
||||
IORANGE_171x, 1, TYPE_PCI171X,
|
||||
16, 8, 2, 16, 16, 1, 0x0fff, 0x0fff,
|
||||
&range_pci1710_3, range_codes_pci1710_3,
|
||||
&range_pci171x_da,
|
||||
10000, 2048},
|
||||
IORANGE_171x, 1, TYPE_PCI171X,
|
||||
16, 8, 2, 16, 16, 1, 0x0fff, 0x0fff,
|
||||
&range_pci1710_3, range_codes_pci1710_3,
|
||||
&range_pci171x_da,
|
||||
10000, 2048},
|
||||
{"pci1710hg", 0x1710,
|
||||
IORANGE_171x, 1, TYPE_PCI171X,
|
||||
16, 8, 2, 16, 16, 1, 0x0fff, 0x0fff,
|
||||
&range_pci1710hg, range_codes_pci1710hg,
|
||||
&range_pci171x_da,
|
||||
10000, 2048},
|
||||
IORANGE_171x, 1, TYPE_PCI171X,
|
||||
16, 8, 2, 16, 16, 1, 0x0fff, 0x0fff,
|
||||
&range_pci1710hg, range_codes_pci1710hg,
|
||||
&range_pci171x_da,
|
||||
10000, 2048},
|
||||
{"pci1711", 0x1711,
|
||||
IORANGE_171x, 1, TYPE_PCI171X,
|
||||
16, 0, 2, 16, 16, 1, 0x0fff, 0x0fff,
|
||||
&range_pci17x1, range_codes_pci17x1, &range_pci171x_da,
|
||||
10000, 512},
|
||||
IORANGE_171x, 1, TYPE_PCI171X,
|
||||
16, 0, 2, 16, 16, 1, 0x0fff, 0x0fff,
|
||||
&range_pci17x1, range_codes_pci17x1, &range_pci171x_da,
|
||||
10000, 512},
|
||||
{"pci1713", 0x1713,
|
||||
IORANGE_171x, 1, TYPE_PCI1713,
|
||||
32, 16, 0, 0, 0, 0, 0x0fff, 0x0000,
|
||||
&range_pci1710_3, range_codes_pci1710_3, NULL,
|
||||
10000, 2048},
|
||||
IORANGE_171x, 1, TYPE_PCI1713,
|
||||
32, 16, 0, 0, 0, 0, 0x0fff, 0x0000,
|
||||
&range_pci1710_3, range_codes_pci1710_3, NULL,
|
||||
10000, 2048},
|
||||
{"pci1720", 0x1720,
|
||||
IORANGE_1720, 0, TYPE_PCI1720,
|
||||
0, 0, 4, 0, 0, 0, 0x0000, 0x0fff,
|
||||
NULL, NULL, &range_pci1720,
|
||||
0, 0},
|
||||
IORANGE_1720, 0, TYPE_PCI1720,
|
||||
0, 0, 4, 0, 0, 0, 0x0000, 0x0fff,
|
||||
NULL, NULL, &range_pci1720,
|
||||
0, 0},
|
||||
{"pci1731", 0x1731,
|
||||
IORANGE_171x, 1, TYPE_PCI171X,
|
||||
16, 0, 0, 16, 16, 0, 0x0fff, 0x0000,
|
||||
&range_pci17x1, range_codes_pci17x1, NULL,
|
||||
10000, 512},
|
||||
IORANGE_171x, 1, TYPE_PCI171X,
|
||||
16, 0, 0, 16, 16, 0, 0x0fff, 0x0000,
|
||||
&range_pci17x1, range_codes_pci17x1, NULL,
|
||||
10000, 512},
|
||||
/* dummy entry corresponding to driver name */
|
||||
{.name = DRV_NAME},
|
||||
};
|
||||
@@ -292,7 +295,7 @@ struct pci1710_private {
|
||||
unsigned int *ai_chanlist; /* actaul chanlist */
|
||||
unsigned int ai_flags; /* flaglist */
|
||||
unsigned int ai_data_len; /* len of data buffer */
|
||||
short *ai_data; /* data buffer */
|
||||
short *ai_data; /* data buffer */
|
||||
unsigned int ai_timer1; /* timers */
|
||||
unsigned int ai_timer2;
|
||||
short ao_data[4]; /* data output buffer */
|
||||
@@ -306,14 +309,18 @@ struct pci1710_private {
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
static int check_channel_list(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
unsigned int *chanlist, unsigned int n_chan);
|
||||
static void setup_channel_list(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
unsigned int *chanlist, unsigned int n_chan, unsigned int seglen);
|
||||
static void start_pacer(struct comedi_device *dev, int mode, unsigned int divisor1,
|
||||
unsigned int divisor2);
|
||||
static int check_channel_list(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
unsigned int *chanlist, unsigned int n_chan);
|
||||
static void setup_channel_list(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
unsigned int *chanlist, unsigned int n_chan,
|
||||
unsigned int seglen);
|
||||
static void start_pacer(struct comedi_device *dev, int mode,
|
||||
unsigned int divisor1, unsigned int divisor2);
|
||||
static int pci1710_reset(struct comedi_device *dev);
|
||||
static int pci171x_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
|
||||
static int pci171x_ai_cancel(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s);
|
||||
|
||||
static const unsigned int muxonechan[] = { 0x0000, 0x0101, 0x0202, 0x0303, 0x0404, 0x0505, 0x0606, 0x0707, /* used for gain list programming */
|
||||
0x0808, 0x0909, 0x0a0a, 0x0b0b, 0x0c0c, 0x0d0d, 0x0e0e, 0x0f0f,
|
||||
@@ -324,8 +331,9 @@ static const unsigned int muxonechan[] = { 0x0000, 0x0101, 0x0202, 0x0303, 0x040
|
||||
/*
|
||||
==============================================================================
|
||||
*/
|
||||
static int pci171x_insn_read_ai(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int pci171x_insn_read_ai(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int n, timeout;
|
||||
#ifdef PCI171x_PARANOIDCHECK
|
||||
@@ -364,10 +372,12 @@ static int pci171x_insn_read_ai(struct comedi_device *dev, struct comedi_subdevi
|
||||
outb(0, dev->iobase + PCI171x_CLRFIFO);
|
||||
outb(0, dev->iobase + PCI171x_CLRINT);
|
||||
data[n] = 0;
|
||||
DPRINTK("adv_pci1710 EDBG: END: pci171x_insn_read_ai(...) n=%d\n", n);
|
||||
DPRINTK
|
||||
("adv_pci1710 EDBG: END: pci171x_insn_read_ai(...) n=%d\n",
|
||||
n);
|
||||
return -ETIME;
|
||||
|
||||
conv_finish:
|
||||
conv_finish:
|
||||
#ifdef PCI171x_PARANOIDCHECK
|
||||
idata = inw(dev->iobase + PCI171x_AD_DATA);
|
||||
if (this_board->cardtype != TYPE_PCI1713)
|
||||
@@ -392,8 +402,9 @@ static int pci171x_insn_read_ai(struct comedi_device *dev, struct comedi_subdevi
|
||||
/*
|
||||
==============================================================================
|
||||
*/
|
||||
static int pci171x_insn_write_ao(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int pci171x_insn_write_ao(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int n, chan, range, ofs;
|
||||
|
||||
@@ -423,8 +434,9 @@ static int pci171x_insn_write_ao(struct comedi_device *dev, struct comedi_subdev
|
||||
/*
|
||||
==============================================================================
|
||||
*/
|
||||
static int pci171x_insn_read_ao(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int pci171x_insn_read_ao(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int n, chan;
|
||||
|
||||
@@ -438,8 +450,9 @@ static int pci171x_insn_read_ao(struct comedi_device *dev, struct comedi_subdevi
|
||||
/*
|
||||
==============================================================================
|
||||
*/
|
||||
static int pci171x_insn_bits_di(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int pci171x_insn_bits_di(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
data[1] = inw(dev->iobase + PCI171x_DI);
|
||||
|
||||
@@ -449,8 +462,9 @@ static int pci171x_insn_bits_di(struct comedi_device *dev, struct comedi_subdevi
|
||||
/*
|
||||
==============================================================================
|
||||
*/
|
||||
static int pci171x_insn_bits_do(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int pci171x_insn_bits_do(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
if (data[0]) {
|
||||
s->state &= ~data[0];
|
||||
@@ -465,8 +479,10 @@ static int pci171x_insn_bits_do(struct comedi_device *dev, struct comedi_subdevi
|
||||
/*
|
||||
==============================================================================
|
||||
*/
|
||||
static int pci171x_insn_counter_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int pci171x_insn_counter_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
unsigned int msb, lsb, ccntrl;
|
||||
int i;
|
||||
@@ -487,8 +503,10 @@ static int pci171x_insn_counter_read(struct comedi_device *dev, struct comedi_su
|
||||
/*
|
||||
==============================================================================
|
||||
*/
|
||||
static int pci171x_insn_counter_write(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int pci171x_insn_counter_write(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
uint msb, lsb, ccntrl, status;
|
||||
|
||||
@@ -515,7 +533,9 @@ static int pci171x_insn_counter_write(struct comedi_device *dev, struct comedi_s
|
||||
==============================================================================
|
||||
*/
|
||||
static int pci171x_insn_counter_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
#ifdef unused
|
||||
/* This doesn't work like a normal Comedi counter config */
|
||||
@@ -550,8 +570,9 @@ static int pci171x_insn_counter_config(struct comedi_device *dev,
|
||||
/*
|
||||
==============================================================================
|
||||
*/
|
||||
static int pci1720_insn_write_ao(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int pci1720_insn_write_ao(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int n, rangereg, chan;
|
||||
|
||||
@@ -596,8 +617,8 @@ static void interrupt_pci1710_every_sample(void *d)
|
||||
}
|
||||
if (m & Status_FF) {
|
||||
printk
|
||||
("comedi%d: A/D FIFO Full status (Fatal Error!) (%4x)\n",
|
||||
dev->minor, m);
|
||||
("comedi%d: A/D FIFO Full status (Fatal Error!) (%4x)\n",
|
||||
dev->minor, m);
|
||||
pci171x_ai_cancel(dev, s);
|
||||
s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
|
||||
comedi_event(dev, s);
|
||||
@@ -613,16 +634,17 @@ static void interrupt_pci1710_every_sample(void *d)
|
||||
DPRINTK("%04x:", sampl);
|
||||
if (this_board->cardtype != TYPE_PCI1713)
|
||||
if ((sampl & 0xf000) !=
|
||||
devpriv->act_chanlist[s->async->cur_chan]) {
|
||||
devpriv->act_chanlist[s->async->cur_chan]) {
|
||||
printk
|
||||
("comedi: A/D data dropout: received data from channel %d, expected %d!\n",
|
||||
(sampl & 0xf000) >> 12,
|
||||
(devpriv->act_chanlist[s->async->
|
||||
cur_chan] & 0xf000) >>
|
||||
12);
|
||||
("comedi: A/D data dropout: received data from channel %d, expected %d!\n",
|
||||
(sampl & 0xf000) >> 12,
|
||||
(devpriv->
|
||||
act_chanlist[s->
|
||||
async->cur_chan] & 0xf000) >>
|
||||
12);
|
||||
pci171x_ai_cancel(dev, s);
|
||||
s->async->events |=
|
||||
COMEDI_CB_EOA | COMEDI_CB_ERROR;
|
||||
COMEDI_CB_EOA | COMEDI_CB_ERROR;
|
||||
comedi_event(dev, s);
|
||||
return;
|
||||
}
|
||||
@@ -631,7 +653,7 @@ static void interrupt_pci1710_every_sample(void *d)
|
||||
comedi_buf_put(s->async, sampl & 0x0fff);
|
||||
#else
|
||||
comedi_buf_put(s->async,
|
||||
inw(dev->iobase + PCI171x_AD_DATA) & 0x0fff);
|
||||
inw(dev->iobase + PCI171x_AD_DATA) & 0x0fff);
|
||||
#endif
|
||||
++s->async->cur_chan;
|
||||
|
||||
@@ -641,7 +663,10 @@ static void interrupt_pci1710_every_sample(void *d)
|
||||
|
||||
if (s->async->cur_chan == 0) { /* one scan done */
|
||||
devpriv->ai_act_scan++;
|
||||
DPRINTK("adv_pci1710 EDBG: EOS1 bic %d bip %d buc %d bup %d\n", s->async->buf_int_count, s->async->buf_int_ptr, s->async->buf_user_count, s->async->buf_user_ptr);
|
||||
DPRINTK
|
||||
("adv_pci1710 EDBG: EOS1 bic %d bip %d buc %d bup %d\n",
|
||||
s->async->buf_int_count, s->async->buf_int_ptr,
|
||||
s->async->buf_user_count, s->async->buf_user_ptr);
|
||||
DPRINTK("adv_pci1710 EDBG: EOS2\n");
|
||||
if ((!devpriv->neverending_ai) && (devpriv->ai_act_scan >= devpriv->ai_scans)) { /* all data sampled */
|
||||
pci171x_ai_cancel(dev, s);
|
||||
@@ -661,8 +686,8 @@ static void interrupt_pci1710_every_sample(void *d)
|
||||
/*
|
||||
==============================================================================
|
||||
*/
|
||||
static int move_block_from_fifo(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
int n, int turn)
|
||||
static int move_block_from_fifo(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, int n, int turn)
|
||||
{
|
||||
int i, j;
|
||||
#ifdef PCI171x_PARANOIDCHECK
|
||||
@@ -677,22 +702,21 @@ static int move_block_from_fifo(struct comedi_device *dev, struct comedi_subdevi
|
||||
if (this_board->cardtype != TYPE_PCI1713)
|
||||
if ((sampl & 0xf000) != devpriv->act_chanlist[j]) {
|
||||
printk
|
||||
("comedi%d: A/D FIFO data dropout: received data from channel %d, expected %d! (%d/%d/%d/%d/%d/%4x)\n",
|
||||
dev->minor, (sampl & 0xf000) >> 12,
|
||||
(devpriv->
|
||||
act_chanlist[j] & 0xf000) >> 12,
|
||||
i, j, devpriv->ai_act_scan, n, turn,
|
||||
sampl);
|
||||
("comedi%d: A/D FIFO data dropout: received data from channel %d, expected %d! (%d/%d/%d/%d/%d/%4x)\n",
|
||||
dev->minor, (sampl & 0xf000) >> 12,
|
||||
(devpriv->act_chanlist[j] & 0xf000) >> 12,
|
||||
i, j, devpriv->ai_act_scan, n, turn,
|
||||
sampl);
|
||||
pci171x_ai_cancel(dev, s);
|
||||
s->async->events |=
|
||||
COMEDI_CB_EOA | COMEDI_CB_ERROR;
|
||||
COMEDI_CB_EOA | COMEDI_CB_ERROR;
|
||||
comedi_event(dev, s);
|
||||
return 1;
|
||||
}
|
||||
comedi_buf_put(s->async, sampl & 0x0fff);
|
||||
#else
|
||||
comedi_buf_put(s->async,
|
||||
inw(dev->iobase + PCI171x_AD_DATA) & 0x0fff);
|
||||
inw(dev->iobase + PCI171x_AD_DATA) & 0x0fff);
|
||||
#endif
|
||||
j++;
|
||||
if (j >= devpriv->ai_n_chan) {
|
||||
@@ -717,7 +741,7 @@ static void interrupt_pci1710_half_fifo(void *d)
|
||||
m = inw(dev->iobase + PCI171x_STATUS);
|
||||
if (!(m & Status_FH)) {
|
||||
printk("comedi%d: A/D FIFO not half full! (%4x)\n",
|
||||
dev->minor, m);
|
||||
dev->minor, m);
|
||||
pci171x_ai_cancel(dev, s);
|
||||
s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
|
||||
comedi_event(dev, s);
|
||||
@@ -725,8 +749,8 @@ static void interrupt_pci1710_half_fifo(void *d)
|
||||
}
|
||||
if (m & Status_FF) {
|
||||
printk
|
||||
("comedi%d: A/D FIFO Full status (Fatal Error!) (%4x)\n",
|
||||
dev->minor, m);
|
||||
("comedi%d: A/D FIFO Full status (Fatal Error!) (%4x)\n",
|
||||
dev->minor, m);
|
||||
pci171x_ai_cancel(dev, s);
|
||||
s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
|
||||
comedi_event(dev, s);
|
||||
@@ -804,7 +828,7 @@ static irqreturn_t interrupt_service_pci1710(int irq, void *d)
|
||||
==============================================================================
|
||||
*/
|
||||
static int pci171x_ai_docmd_and_mode(int mode, struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
unsigned int divisor1, divisor2;
|
||||
unsigned int seglen;
|
||||
@@ -814,11 +838,11 @@ static int pci171x_ai_docmd_and_mode(int mode, struct comedi_device *dev,
|
||||
start_pacer(dev, -1, 0, 0); /* stop pacer */
|
||||
|
||||
seglen = check_channel_list(dev, s, devpriv->ai_chanlist,
|
||||
devpriv->ai_n_chan);
|
||||
devpriv->ai_n_chan);
|
||||
if (seglen < 1)
|
||||
return -EINVAL;
|
||||
setup_channel_list(dev, s, devpriv->ai_chanlist,
|
||||
devpriv->ai_n_chan, seglen);
|
||||
devpriv->ai_n_chan, seglen);
|
||||
|
||||
outb(0, dev->iobase + PCI171x_CLRFIFO);
|
||||
outb(0, dev->iobase + PCI171x_CLRINT);
|
||||
@@ -840,7 +864,7 @@ static int pci171x_ai_docmd_and_mode(int mode, struct comedi_device *dev,
|
||||
|
||||
if ((devpriv->ai_scans == 0) || (devpriv->ai_scans == -1)) {
|
||||
devpriv->neverending_ai = 1;
|
||||
} /* well, user want neverending */
|
||||
} /* well, user want neverending */
|
||||
else {
|
||||
devpriv->neverending_ai = 0;
|
||||
}
|
||||
@@ -853,16 +877,19 @@ static int pci171x_ai_docmd_and_mode(int mode, struct comedi_device *dev,
|
||||
if (mode == 2) {
|
||||
devpriv->ai_et_CntrlReg = devpriv->CntrlReg;
|
||||
devpriv->CntrlReg &=
|
||||
~(Control_PACER | Control_ONEFH | Control_GATE);
|
||||
~(Control_PACER | Control_ONEFH | Control_GATE);
|
||||
devpriv->CntrlReg |= Control_EXT;
|
||||
devpriv->ai_et = 1;
|
||||
} else {
|
||||
devpriv->ai_et = 0;
|
||||
}
|
||||
i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
|
||||
&divisor2, &devpriv->ai_timer1,
|
||||
devpriv->ai_flags & TRIG_ROUND_MASK);
|
||||
DPRINTK("adv_pci1710 EDBG: OSC base=%u div1=%u div2=%u timer=%u\n", devpriv->i8254_osc_base, divisor1, divisor2, devpriv->ai_timer1);
|
||||
&divisor2, &devpriv->ai_timer1,
|
||||
devpriv->ai_flags & TRIG_ROUND_MASK);
|
||||
DPRINTK
|
||||
("adv_pci1710 EDBG: OSC base=%u div1=%u div2=%u timer=%u\n",
|
||||
devpriv->i8254_osc_base, divisor1, divisor2,
|
||||
devpriv->ai_timer1);
|
||||
outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
|
||||
if (mode != 2) {
|
||||
/* start pacer */
|
||||
@@ -889,21 +916,22 @@ static int pci171x_ai_docmd_and_mode(int mode, struct comedi_device *dev,
|
||||
static void pci171x_cmdtest_out(int e, struct comedi_cmd *cmd)
|
||||
{
|
||||
printk("adv_pci1710 e=%d startsrc=%x scansrc=%x convsrc=%x\n", e,
|
||||
cmd->start_src, cmd->scan_begin_src, cmd->convert_src);
|
||||
cmd->start_src, cmd->scan_begin_src, cmd->convert_src);
|
||||
printk("adv_pci1710 e=%d startarg=%d scanarg=%d convarg=%d\n", e,
|
||||
cmd->start_arg, cmd->scan_begin_arg, cmd->convert_arg);
|
||||
cmd->start_arg, cmd->scan_begin_arg, cmd->convert_arg);
|
||||
printk("adv_pci1710 e=%d stopsrc=%x scanend=%x\n", e, cmd->stop_src,
|
||||
cmd->scan_end_src);
|
||||
cmd->scan_end_src);
|
||||
printk("adv_pci1710 e=%d stoparg=%d scanendarg=%d chanlistlen=%d\n",
|
||||
e, cmd->stop_arg, cmd->scan_end_arg, cmd->chanlist_len);
|
||||
e, cmd->stop_arg, cmd->scan_end_arg, cmd->chanlist_len);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
*/
|
||||
static int pci171x_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd)
|
||||
static int pci171x_ai_cmdtest(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd)
|
||||
{
|
||||
int err = 0;
|
||||
int tmp, divisor1, divisor2;
|
||||
@@ -943,7 +971,9 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
|
||||
#ifdef PCI171X_EXTDEBUG
|
||||
pci171x_cmdtest_out(1, cmd);
|
||||
#endif
|
||||
DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=1\n", err);
|
||||
DPRINTK
|
||||
("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=1\n",
|
||||
err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -974,7 +1004,9 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
|
||||
#ifdef PCI171X_EXTDEBUG
|
||||
pci171x_cmdtest_out(2, cmd);
|
||||
#endif
|
||||
DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=2\n", err);
|
||||
DPRINTK
|
||||
("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=2\n",
|
||||
err);
|
||||
return 2;
|
||||
}
|
||||
|
||||
@@ -1030,7 +1062,9 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
|
||||
#ifdef PCI171X_EXTDEBUG
|
||||
pci171x_cmdtest_out(3, cmd);
|
||||
#endif
|
||||
DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=3\n", err);
|
||||
DPRINTK
|
||||
("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=3\n",
|
||||
err);
|
||||
return 3;
|
||||
}
|
||||
|
||||
@@ -1039,8 +1073,8 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
|
||||
if (cmd->convert_src == TRIG_TIMER) {
|
||||
tmp = cmd->convert_arg;
|
||||
i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
|
||||
&divisor2, &cmd->convert_arg,
|
||||
cmd->flags & TRIG_ROUND_MASK);
|
||||
&divisor2, &cmd->convert_arg,
|
||||
cmd->flags & TRIG_ROUND_MASK);
|
||||
if (cmd->convert_arg < this_board->ai_ns_min)
|
||||
cmd->convert_arg = this_board->ai_ns_min;
|
||||
if (tmp != cmd->convert_arg)
|
||||
@@ -1048,7 +1082,9 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
|
||||
}
|
||||
|
||||
if (err) {
|
||||
DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=4\n", err);
|
||||
DPRINTK
|
||||
("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=4\n",
|
||||
err);
|
||||
return 4;
|
||||
}
|
||||
|
||||
@@ -1056,7 +1092,7 @@ static int pci171x_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
|
||||
|
||||
if (cmd->chanlist) {
|
||||
if (!check_channel_list(dev, s, cmd->chanlist,
|
||||
cmd->chanlist_len))
|
||||
cmd->chanlist_len))
|
||||
return 5; /* incorrect channels list */
|
||||
}
|
||||
|
||||
@@ -1090,7 +1126,8 @@ static int pci171x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
if (cmd->convert_src == TRIG_TIMER) { /* mode 1 and 2 */
|
||||
devpriv->ai_timer1 = cmd->convert_arg;
|
||||
return pci171x_ai_docmd_and_mode(cmd->start_src ==
|
||||
TRIG_EXT ? 2 : 1, dev, s);
|
||||
TRIG_EXT ? 2 : 1, dev,
|
||||
s);
|
||||
}
|
||||
if (cmd->convert_src == TRIG_EXT) { /* mode 3 */
|
||||
return pci171x_ai_docmd_and_mode(3, dev, s);
|
||||
@@ -1106,8 +1143,9 @@ static int pci171x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
If it's ok, then program scan/gain logic.
|
||||
This works for all cards.
|
||||
*/
|
||||
static int check_channel_list(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
unsigned int *chanlist, unsigned int n_chan)
|
||||
static int check_channel_list(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
unsigned int *chanlist, unsigned int n_chan)
|
||||
{
|
||||
unsigned int chansegment[32];
|
||||
unsigned int i, nowmustbechan, seglen, segpos;
|
||||
@@ -1128,18 +1166,18 @@ static int check_channel_list(struct comedi_device *dev, struct comedi_subdevice
|
||||
if (CR_CHAN(chanlist[i]) & 1) /* odd channel cann't by differencial */
|
||||
if (CR_AREF(chanlist[i]) == AREF_DIFF) {
|
||||
comedi_error(dev,
|
||||
"Odd channel can't be differential input!\n");
|
||||
"Odd channel can't be differential input!\n");
|
||||
return 0;
|
||||
}
|
||||
nowmustbechan =
|
||||
(CR_CHAN(chansegment[i - 1]) + 1) % s->n_chan;
|
||||
(CR_CHAN(chansegment[i - 1]) + 1) % s->n_chan;
|
||||
if (CR_AREF(chansegment[i - 1]) == AREF_DIFF)
|
||||
nowmustbechan = (nowmustbechan + 1) % s->n_chan;
|
||||
if (nowmustbechan != CR_CHAN(chanlist[i])) { /* channel list isn't continous :-( */
|
||||
printk
|
||||
("channel list must be continous! chanlist[%i]=%d but must be %d or %d!\n",
|
||||
i, CR_CHAN(chanlist[i]), nowmustbechan,
|
||||
CR_CHAN(chanlist[0]));
|
||||
("channel list must be continous! chanlist[%i]=%d but must be %d or %d!\n",
|
||||
i, CR_CHAN(chanlist[i]), nowmustbechan,
|
||||
CR_CHAN(chanlist[0]));
|
||||
return 0;
|
||||
}
|
||||
chansegment[i] = chanlist[i]; /* well, this is next correct channel in list */
|
||||
@@ -1149,13 +1187,13 @@ static int check_channel_list(struct comedi_device *dev, struct comedi_subdevice
|
||||
/* printk("%d %d=%d %d\n",CR_CHAN(chansegment[i%seglen]),CR_RANGE(chansegment[i%seglen]),CR_CHAN(chanlist[i]),CR_RANGE(chanlist[i])); */
|
||||
if (chanlist[i] != chansegment[i % seglen]) {
|
||||
printk
|
||||
("bad channel, reference or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n",
|
||||
i, CR_CHAN(chansegment[i]),
|
||||
CR_RANGE(chansegment[i]),
|
||||
CR_AREF(chansegment[i]),
|
||||
CR_CHAN(chanlist[i % seglen]),
|
||||
CR_RANGE(chanlist[i % seglen]),
|
||||
CR_AREF(chansegment[i % seglen]));
|
||||
("bad channel, reference or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n",
|
||||
i, CR_CHAN(chansegment[i]),
|
||||
CR_RANGE(chansegment[i]),
|
||||
CR_AREF(chansegment[i]),
|
||||
CR_CHAN(chanlist[i % seglen]),
|
||||
CR_RANGE(chanlist[i % seglen]),
|
||||
CR_AREF(chansegment[i % seglen]));
|
||||
return 0; /* chan/gain list is strange */
|
||||
}
|
||||
}
|
||||
@@ -1165,8 +1203,10 @@ static int check_channel_list(struct comedi_device *dev, struct comedi_subdevice
|
||||
return seglen;
|
||||
}
|
||||
|
||||
static void setup_channel_list(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
unsigned int *chanlist, unsigned int n_chan, unsigned int seglen)
|
||||
static void setup_channel_list(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
unsigned int *chanlist, unsigned int n_chan,
|
||||
unsigned int seglen)
|
||||
{
|
||||
unsigned int i, range, chanprog;
|
||||
|
||||
@@ -1185,14 +1225,14 @@ static void setup_channel_list(struct comedi_device *dev, struct comedi_subdevic
|
||||
outw(range, dev->iobase + PCI171x_RANGE); /* select gain */
|
||||
#ifdef PCI171x_PARANOIDCHECK
|
||||
devpriv->act_chanlist[i] =
|
||||
(CR_CHAN(chanlist[i]) << 12) & 0xf000;
|
||||
(CR_CHAN(chanlist[i]) << 12) & 0xf000;
|
||||
#endif
|
||||
DPRINTK("GS: %2d. [%4x]=%4x %4x\n", i, chanprog, range,
|
||||
devpriv->act_chanlist[i]);
|
||||
}
|
||||
|
||||
devpriv->ai_et_MuxVal =
|
||||
CR_CHAN(chanlist[0]) | (CR_CHAN(chanlist[seglen - 1]) << 8);
|
||||
CR_CHAN(chanlist[0]) | (CR_CHAN(chanlist[seglen - 1]) << 8);
|
||||
outw(devpriv->ai_et_MuxVal, dev->iobase + PCI171x_MUX); /* select channel interval to scan */
|
||||
DPRINTK("MUX: %4x L%4x.H%4x\n",
|
||||
CR_CHAN(chanlist[0]) | (CR_CHAN(chanlist[seglen - 1]) << 8),
|
||||
@@ -1202,8 +1242,8 @@ static void setup_channel_list(struct comedi_device *dev, struct comedi_subdevic
|
||||
/*
|
||||
==============================================================================
|
||||
*/
|
||||
static void start_pacer(struct comedi_device *dev, int mode, unsigned int divisor1,
|
||||
unsigned int divisor2)
|
||||
static void start_pacer(struct comedi_device *dev, int mode,
|
||||
unsigned int divisor1, unsigned int divisor2)
|
||||
{
|
||||
DPRINTK("adv_pci1710 EDBG: BGN: start_pacer(%d,%u,%u)\n", mode,
|
||||
divisor1, divisor2);
|
||||
@@ -1222,7 +1262,8 @@ static void start_pacer(struct comedi_device *dev, int mode, unsigned int diviso
|
||||
/*
|
||||
==============================================================================
|
||||
*/
|
||||
static int pci171x_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
static int pci171x_ai_cancel(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cancel(...)\n");
|
||||
|
||||
@@ -1318,7 +1359,8 @@ static int pci1710_reset(struct comedi_device *dev)
|
||||
/*
|
||||
==============================================================================
|
||||
*/
|
||||
static int pci1710_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
static int pci1710_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it)
|
||||
{
|
||||
struct comedi_subdevice *s;
|
||||
int ret, subdev, n_subdevices;
|
||||
@@ -1347,36 +1389,35 @@ static int pci1710_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
pcidev = NULL;
|
||||
board_index = this_board - boardtypes;
|
||||
while (NULL != (pcidev = pci_get_device(PCI_VENDOR_ID_ADVANTECH,
|
||||
PCI_ANY_ID, pcidev))) {
|
||||
if (strcmp (this_board->name, DRV_NAME) == 0)
|
||||
{
|
||||
for (i = 0; i < n_boardtypes; ++i)
|
||||
{
|
||||
if (pcidev->device == boardtypes[i].device_id)
|
||||
{
|
||||
PCI_ANY_ID, pcidev))) {
|
||||
if (strcmp(this_board->name, DRV_NAME) == 0) {
|
||||
for (i = 0; i < n_boardtypes; ++i) {
|
||||
if (pcidev->device == boardtypes[i].device_id) {
|
||||
board_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == n_boardtypes) continue;
|
||||
}else
|
||||
{
|
||||
if (pcidev->device != boardtypes[board_index].device_id) continue;
|
||||
if (i == n_boardtypes)
|
||||
continue;
|
||||
} else {
|
||||
if (pcidev->device != boardtypes[board_index].device_id)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Found matching vendor/device. */
|
||||
if (opt_bus || opt_slot) {
|
||||
/* Check bus/slot. */
|
||||
if (opt_bus != pcidev->bus->number
|
||||
|| opt_slot != PCI_SLOT(pcidev->devfn))
|
||||
|| opt_slot != PCI_SLOT(pcidev->devfn))
|
||||
continue; /* no match */
|
||||
}
|
||||
/*
|
||||
* Look for device that isn't in use.
|
||||
* Enable PCI device and request regions.
|
||||
*/
|
||||
* Look for device that isn't in use.
|
||||
* Enable PCI device and request regions.
|
||||
*/
|
||||
if (comedi_pci_enable(pcidev, DRV_NAME)) {
|
||||
errstr = "failed to enable PCI device and request regions!";
|
||||
errstr =
|
||||
"failed to enable PCI device and request regions!";
|
||||
continue;
|
||||
}
|
||||
/* fixup board_ptr in case we were using the dummy entry with the driver name */
|
||||
@@ -1387,7 +1428,7 @@ static int pci1710_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
if (!pcidev) {
|
||||
if (opt_bus || opt_slot) {
|
||||
printk(" - Card at b:s %d:%d %s\n",
|
||||
opt_bus, opt_slot, errstr);
|
||||
opt_bus, opt_slot, errstr);
|
||||
} else {
|
||||
printk(" - Card %s\n", errstr);
|
||||
}
|
||||
@@ -1401,7 +1442,7 @@ static int pci1710_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
iobase = pci_resource_start(pcidev, 2);
|
||||
|
||||
printk(", b:s:f=%d:%d:%d, io=0x%4lx", pci_bus, pci_slot, pci_func,
|
||||
iobase);
|
||||
iobase);
|
||||
|
||||
dev->iobase = iobase;
|
||||
|
||||
@@ -1434,8 +1475,8 @@ static int pci1710_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
IRQF_SHARED, "Advantech PCI-1710",
|
||||
dev)) {
|
||||
printk
|
||||
(", unable to allocate IRQ %d, DISABLING IT",
|
||||
irq);
|
||||
(", unable to allocate IRQ %d, DISABLING IT",
|
||||
irq);
|
||||
irq = 0; /* Can't use IRQ */
|
||||
} else {
|
||||
printk(", irq=%u", irq);
|
||||
|
||||
@@ -95,8 +95,8 @@ configures all channels in the same group.
|
||||
/* static unsigned short pci_list_builded=0; =1 list of card is know */
|
||||
|
||||
static const struct comedi_lrange range_pci1723 = { 1, {
|
||||
BIP_RANGE(10)
|
||||
}
|
||||
BIP_RANGE(10)
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -116,23 +116,24 @@ struct pci1723_board {
|
||||
|
||||
static const struct pci1723_board boardtypes[] = {
|
||||
{
|
||||
.name = "pci1723",
|
||||
.vendor_id = ADVANTECH_VENDOR,
|
||||
.device_id = 0x1723,
|
||||
.iorange = IORANGE_1723,
|
||||
.cardtype = TYPE_PCI1723,
|
||||
.n_aochan = 8,
|
||||
.n_diochan = 16,
|
||||
.ao_maxdata = 0xffff,
|
||||
.rangelist_ao = &range_pci1723,
|
||||
},
|
||||
.name = "pci1723",
|
||||
.vendor_id = ADVANTECH_VENDOR,
|
||||
.device_id = 0x1723,
|
||||
.iorange = IORANGE_1723,
|
||||
.cardtype = TYPE_PCI1723,
|
||||
.n_aochan = 8,
|
||||
.n_diochan = 16,
|
||||
.ao_maxdata = 0xffff,
|
||||
.rangelist_ao = &range_pci1723,
|
||||
},
|
||||
};
|
||||
|
||||
/* This is used by modprobe to translate PCI IDs to drivers. Should
|
||||
* only be used for PCI and ISA-PnP devices */
|
||||
static DEFINE_PCI_DEVICE_TABLE(pci1723_pci_table) = {
|
||||
{PCI_VENDOR_ID_ADVANTECH, 0x1723, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{0}
|
||||
{
|
||||
PCI_VENDOR_ID_ADVANTECH, 0x1723, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
0}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, pci1723_pci_table);
|
||||
@@ -143,7 +144,8 @@ MODULE_DEVICE_TABLE(pci, pci1723_pci_table);
|
||||
* the board, and also about the kernel module that contains
|
||||
* the device code.
|
||||
*/
|
||||
static int pci1723_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int pci1723_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int pci1723_detach(struct comedi_device *dev);
|
||||
|
||||
#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pci1723_board))
|
||||
@@ -189,7 +191,7 @@ static int pci1723_reset(struct comedi_device *dev)
|
||||
/* set all ranges to +/- 10V */
|
||||
devpriv->da_range[i] = 0;
|
||||
outw(((devpriv->da_range[i] << 4) | i),
|
||||
PCI1723_RANGE_CALIBRATION_MODE);
|
||||
PCI1723_RANGE_CALIBRATION_MODE);
|
||||
}
|
||||
|
||||
outw(0, dev->iobase + PCI1723_CHANGE_CHA_OUTPUT_TYPE_STROBE); /* update ranges */
|
||||
@@ -202,8 +204,9 @@ static int pci1723_reset(struct comedi_device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pci1723_insn_read_ao(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int pci1723_insn_read_ao(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int n, chan;
|
||||
|
||||
@@ -218,8 +221,9 @@ static int pci1723_insn_read_ao(struct comedi_device *dev, struct comedi_subdevi
|
||||
/*
|
||||
analog data output;
|
||||
*/
|
||||
static int pci1723_ao_write_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int pci1723_ao_write_winsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int n, chan;
|
||||
chan = CR_CHAN(insn->chanspec);
|
||||
@@ -238,8 +242,9 @@ static int pci1723_ao_write_winsn(struct comedi_device *dev, struct comedi_subde
|
||||
/*
|
||||
digital i/o config/query
|
||||
*/
|
||||
static int pci1723_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int pci1723_dio_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
unsigned int mask;
|
||||
unsigned int bits;
|
||||
@@ -278,8 +283,9 @@ static int pci1723_dio_insn_config(struct comedi_device *dev, struct comedi_subd
|
||||
/*
|
||||
digital i/o bits read/write
|
||||
*/
|
||||
static int pci1723_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int pci1723_dio_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
if (data[0]) {
|
||||
s->state &= ~data[0];
|
||||
@@ -294,7 +300,8 @@ static int pci1723_dio_insn_bits(struct comedi_device *dev, struct comedi_subdev
|
||||
* Attach is called by the Comedi core to configure the driver
|
||||
* for a pci1723 board.
|
||||
*/
|
||||
static int pci1723_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
static int pci1723_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it)
|
||||
{
|
||||
struct comedi_subdevice *s;
|
||||
int ret, subdev, n_subdevices;
|
||||
@@ -304,8 +311,7 @@ static int pci1723_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
int opt_bus, opt_slot;
|
||||
const char *errstr;
|
||||
|
||||
printk("comedi%d: adv_pci1723: board=%s", dev->minor,
|
||||
this_board->name);
|
||||
printk("comedi%d: adv_pci1723: board=%s", dev->minor, this_board->name);
|
||||
|
||||
opt_bus = it->options[0];
|
||||
opt_slot = it->options[1];
|
||||
@@ -321,12 +327,12 @@ static int pci1723_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
pcidev = NULL;
|
||||
while (NULL != (pcidev =
|
||||
pci_get_device(PCI_VENDOR_ID_ADVANTECH,
|
||||
this_board->device_id, pcidev))) {
|
||||
this_board->device_id, pcidev))) {
|
||||
/* Found matching vendor/device. */
|
||||
if (opt_bus || opt_slot) {
|
||||
/* Check bus/slot. */
|
||||
if (opt_bus != pcidev->bus->number
|
||||
|| opt_slot != PCI_SLOT(pcidev->devfn))
|
||||
|| opt_slot != PCI_SLOT(pcidev->devfn))
|
||||
continue; /* no match */
|
||||
}
|
||||
/*
|
||||
@@ -334,7 +340,8 @@ static int pci1723_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
* Enable PCI device and request regions.
|
||||
*/
|
||||
if (comedi_pci_enable(pcidev, "adv_pci1723")) {
|
||||
errstr = "failed to enable PCI device and request regions!";
|
||||
errstr =
|
||||
"failed to enable PCI device and request regions!";
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
@@ -343,7 +350,7 @@ static int pci1723_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
if (!pcidev) {
|
||||
if (opt_bus || opt_slot) {
|
||||
printk(" - Card at b:s %d:%d %s\n",
|
||||
opt_bus, opt_slot, errstr);
|
||||
opt_bus, opt_slot, errstr);
|
||||
} else {
|
||||
printk(" - Card %s\n", errstr);
|
||||
}
|
||||
@@ -356,7 +363,7 @@ static int pci1723_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
iobase = pci_resource_start(pcidev, 2);
|
||||
|
||||
printk(", b:s:f=%d:%d:%d, io=0x%4x", pci_bus, pci_slot, pci_func,
|
||||
iobase);
|
||||
iobase);
|
||||
|
||||
dev->iobase = iobase;
|
||||
|
||||
@@ -416,7 +423,7 @@ static int pci1723_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
s = dev->subdevices + subdev;
|
||||
s->type = COMEDI_SUBD_DIO;
|
||||
s->subdev_flags =
|
||||
SDF_READABLE | SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
|
||||
SDF_READABLE | SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
|
||||
s->n_chan = this_board->n_diochan;
|
||||
s->maxdata = 1;
|
||||
s->len_chanlist = this_board->n_diochan;
|
||||
|
||||
@@ -84,13 +84,13 @@ enum hw_io_access {
|
||||
#define PCI173x_BOARDID 4 /* R: Board I/D switch for 1730/3/4 */
|
||||
|
||||
/* Advantech PCI-1736UP */
|
||||
#define PCI1736_IDI 0 /* R: Isolated digital input 0-15 */
|
||||
#define PCI1736_IDO 0 /* W: Isolated digital output 0-15 */
|
||||
#define PCI1736_3_INT_EN 0x08 /* R/W: enable/disable interrupts */
|
||||
#define PCI1736_3_INT_RF 0x0c /* R/W: set falling/raising edge for interrupts */
|
||||
#define PCI1736_3_INT_CLR 0x10 /* R/W: clear interrupts */
|
||||
#define PCI1736_BOARDID 4 /* R: Board I/D switch for 1736UP */
|
||||
#define PCI1736_MAINREG 0 /* Normal register (2) doesn't work */
|
||||
#define PCI1736_IDI 0 /* R: Isolated digital input 0-15 */
|
||||
#define PCI1736_IDO 0 /* W: Isolated digital output 0-15 */
|
||||
#define PCI1736_3_INT_EN 0x08 /* R/W: enable/disable interrupts */
|
||||
#define PCI1736_3_INT_RF 0x0c /* R/W: set falling/raising edge for interrupts */
|
||||
#define PCI1736_3_INT_CLR 0x10 /* R/W: clear interrupts */
|
||||
#define PCI1736_BOARDID 4 /* R: Board I/D switch for 1736UP */
|
||||
#define PCI1736_MAINREG 0 /* Normal register (2) doesn't work */
|
||||
|
||||
/* Advantech PCI-1750 */
|
||||
#define PCI1750_IDI 0 /* R: Isolated digital input 0-15 */
|
||||
@@ -183,7 +183,8 @@ enum hw_io_access {
|
||||
|
||||
#define OMBCMD_RETRY 0x03 /* 3 times try request before error */
|
||||
|
||||
static int pci_dio_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int pci_dio_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int pci_dio_detach(struct comedi_device *dev);
|
||||
|
||||
struct diosubd_data {
|
||||
@@ -207,117 +208,118 @@ struct dio_boardtype {
|
||||
};
|
||||
|
||||
static DEFINE_PCI_DEVICE_TABLE(pci_dio_pci_table) = {
|
||||
{PCI_VENDOR_ID_ADVANTECH, 0x1730, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_ADVANTECH, 0x1733, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_ADVANTECH, 0x1734, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_ADVANTECH, 0x1736, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_ADVANTECH, 0x1750, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_ADVANTECH, 0x1751, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_ADVANTECH, 0x1752, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_ADVANTECH, 0x1753, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_ADVANTECH, 0x1754, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_ADVANTECH, 0x1756, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_ADVANTECH, 0x1760, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_ADVANTECH, 0x1762, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{0}
|
||||
{
|
||||
PCI_VENDOR_ID_ADVANTECH, 0x1730, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_ADVANTECH, 0x1733, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_ADVANTECH, 0x1734, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_ADVANTECH, 0x1736, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_ADVANTECH, 0x1750, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_ADVANTECH, 0x1751, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_ADVANTECH, 0x1752, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_ADVANTECH, 0x1753, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_ADVANTECH, 0x1754, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_ADVANTECH, 0x1756, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_ADVANTECH, 0x1760, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_ADVANTECH, 0x1762, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
0}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, pci_dio_pci_table);
|
||||
|
||||
static const struct dio_boardtype boardtypes[] = {
|
||||
{"pci1730", PCI_VENDOR_ID_ADVANTECH, 0x1730, PCIDIO_MAINREG,
|
||||
TYPE_PCI1730,
|
||||
{{16, PCI1730_DI, 2, 0}, {16, PCI1730_IDI, 2, 0}},
|
||||
{{16, PCI1730_DO, 2, 0}, {16, PCI1730_IDO, 2, 0}},
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{4, PCI173x_BOARDID, 1, SDF_INTERNAL},
|
||||
IO_8b,
|
||||
},
|
||||
TYPE_PCI1730,
|
||||
{{16, PCI1730_DI, 2, 0}, {16, PCI1730_IDI, 2, 0}},
|
||||
{{16, PCI1730_DO, 2, 0}, {16, PCI1730_IDO, 2, 0}},
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{4, PCI173x_BOARDID, 1, SDF_INTERNAL},
|
||||
IO_8b,
|
||||
},
|
||||
{"pci1733", PCI_VENDOR_ID_ADVANTECH, 0x1733, PCIDIO_MAINREG,
|
||||
TYPE_PCI1733,
|
||||
{{0, 0, 0, 0}, {32, PCI1733_IDI, 4, 0}},
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{4, PCI173x_BOARDID, 1, SDF_INTERNAL},
|
||||
IO_8b},
|
||||
TYPE_PCI1733,
|
||||
{{0, 0, 0, 0}, {32, PCI1733_IDI, 4, 0}},
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{4, PCI173x_BOARDID, 1, SDF_INTERNAL},
|
||||
IO_8b},
|
||||
{"pci1734", PCI_VENDOR_ID_ADVANTECH, 0x1734, PCIDIO_MAINREG,
|
||||
TYPE_PCI1734,
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{{0, 0, 0, 0}, {32, PCI1734_IDO, 4, 0}},
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{4, PCI173x_BOARDID, 1, SDF_INTERNAL},
|
||||
IO_8b},
|
||||
TYPE_PCI1734,
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{{0, 0, 0, 0}, {32, PCI1734_IDO, 4, 0}},
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{4, PCI173x_BOARDID, 1, SDF_INTERNAL},
|
||||
IO_8b},
|
||||
{"pci1736", PCI_VENDOR_ID_ADVANTECH, 0x1736, PCI1736_MAINREG,
|
||||
TYPE_PCI1736,
|
||||
{{0, 0, 0, 0}, {16, PCI1736_IDI, 2, 0}},
|
||||
{{0, 0, 0, 0}, {16, PCI1736_IDO, 2, 0}},
|
||||
{{ 0, 0, 0, 0}, { 0, 0, 0, 0}},
|
||||
{ 4, PCI1736_BOARDID, 1, SDF_INTERNAL},
|
||||
IO_8b,
|
||||
},
|
||||
TYPE_PCI1736,
|
||||
{{0, 0, 0, 0}, {16, PCI1736_IDI, 2, 0}},
|
||||
{{0, 0, 0, 0}, {16, PCI1736_IDO, 2, 0}},
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{4, PCI1736_BOARDID, 1, SDF_INTERNAL},
|
||||
IO_8b,
|
||||
},
|
||||
{"pci1750", PCI_VENDOR_ID_ADVANTECH, 0x1750, PCIDIO_MAINREG,
|
||||
TYPE_PCI1750,
|
||||
{{0, 0, 0, 0}, {16, PCI1750_IDI, 2, 0}},
|
||||
{{0, 0, 0, 0}, {16, PCI1750_IDO, 2, 0}},
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{0, 0, 0, 0},
|
||||
IO_8b},
|
||||
TYPE_PCI1750,
|
||||
{{0, 0, 0, 0}, {16, PCI1750_IDI, 2, 0}},
|
||||
{{0, 0, 0, 0}, {16, PCI1750_IDO, 2, 0}},
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{0, 0, 0, 0},
|
||||
IO_8b},
|
||||
{"pci1751", PCI_VENDOR_ID_ADVANTECH, 0x1751, PCIDIO_MAINREG,
|
||||
TYPE_PCI1751,
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{{48, PCI1751_DIO, 2, 0}, {0, 0, 0, 0}},
|
||||
{0, 0, 0, 0},
|
||||
IO_8b},
|
||||
TYPE_PCI1751,
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{{48, PCI1751_DIO, 2, 0}, {0, 0, 0, 0}},
|
||||
{0, 0, 0, 0},
|
||||
IO_8b},
|
||||
{"pci1752", PCI_VENDOR_ID_ADVANTECH, 0x1752, PCIDIO_MAINREG,
|
||||
TYPE_PCI1752,
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{{32, PCI1752_IDO, 2, 0}, {32, PCI1752_IDO2, 2, 0}},
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{4, PCI175x_BOARDID, 1, SDF_INTERNAL},
|
||||
IO_16b},
|
||||
TYPE_PCI1752,
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{{32, PCI1752_IDO, 2, 0}, {32, PCI1752_IDO2, 2, 0}},
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{4, PCI175x_BOARDID, 1, SDF_INTERNAL},
|
||||
IO_16b},
|
||||
{"pci1753", PCI_VENDOR_ID_ADVANTECH, 0x1753, PCIDIO_MAINREG,
|
||||
TYPE_PCI1753,
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{{96, PCI1753_DIO, 4, 0}, {0, 0, 0, 0}},
|
||||
{0, 0, 0, 0},
|
||||
IO_8b},
|
||||
TYPE_PCI1753,
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{{96, PCI1753_DIO, 4, 0}, {0, 0, 0, 0}},
|
||||
{0, 0, 0, 0},
|
||||
IO_8b},
|
||||
{"pci1753e", PCI_VENDOR_ID_ADVANTECH, 0x1753, PCIDIO_MAINREG,
|
||||
TYPE_PCI1753E,
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{{96, PCI1753_DIO, 4, 0}, {96, PCI1753E_DIO, 4, 0}},
|
||||
{0, 0, 0, 0},
|
||||
IO_8b},
|
||||
TYPE_PCI1753E,
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{{96, PCI1753_DIO, 4, 0}, {96, PCI1753E_DIO, 4, 0}},
|
||||
{0, 0, 0, 0},
|
||||
IO_8b},
|
||||
{"pci1754", PCI_VENDOR_ID_ADVANTECH, 0x1754, PCIDIO_MAINREG,
|
||||
TYPE_PCI1754,
|
||||
{{32, PCI1754_IDI, 2, 0}, {32, PCI1754_IDI2, 2, 0}},
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{4, PCI175x_BOARDID, 1, SDF_INTERNAL},
|
||||
IO_16b},
|
||||
TYPE_PCI1754,
|
||||
{{32, PCI1754_IDI, 2, 0}, {32, PCI1754_IDI2, 2, 0}},
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{4, PCI175x_BOARDID, 1, SDF_INTERNAL},
|
||||
IO_16b},
|
||||
{"pci1756", PCI_VENDOR_ID_ADVANTECH, 0x1756, PCIDIO_MAINREG,
|
||||
TYPE_PCI1756,
|
||||
{{0, 0, 0, 0}, {32, PCI1756_IDI, 2, 0}},
|
||||
{{0, 0, 0, 0}, {32, PCI1756_IDO, 2, 0}},
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{4, PCI175x_BOARDID, 1, SDF_INTERNAL},
|
||||
IO_16b},
|
||||
TYPE_PCI1756,
|
||||
{{0, 0, 0, 0}, {32, PCI1756_IDI, 2, 0}},
|
||||
{{0, 0, 0, 0}, {32, PCI1756_IDO, 2, 0}},
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{4, PCI175x_BOARDID, 1, SDF_INTERNAL},
|
||||
IO_16b},
|
||||
{"pci1760", PCI_VENDOR_ID_ADVANTECH, 0x1760, 0,
|
||||
TYPE_PCI1760,
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}}, /* This card have own setup work */
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{0, 0, 0, 0},
|
||||
IO_8b},
|
||||
TYPE_PCI1760,
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}}, /* This card have own setup work */
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{0, 0, 0, 0},
|
||||
IO_8b},
|
||||
{"pci1762", PCI_VENDOR_ID_ADVANTECH, 0x1762, PCIDIO_MAINREG,
|
||||
TYPE_PCI1762,
|
||||
{{0, 0, 0, 0}, {16, PCI1762_IDI, 1, 0}},
|
||||
{{0, 0, 0, 0}, {16, PCI1762_RO, 1, 0}},
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{4, PCI1762_BOARDID, 1, SDF_INTERNAL},
|
||||
IO_16b}
|
||||
TYPE_PCI1762,
|
||||
{{0, 0, 0, 0}, {16, PCI1762_IDI, 1, 0}},
|
||||
{{0, 0, 0, 0}, {16, PCI1762_RO, 1, 0}},
|
||||
{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||
{4, PCI1762_BOARDID, 1, SDF_INTERNAL},
|
||||
IO_16b}
|
||||
};
|
||||
|
||||
#define n_boardtypes (sizeof(boardtypes)/sizeof(struct dio_boardtype))
|
||||
@@ -357,8 +359,9 @@ static struct pci_dio_private *pci_priv = NULL; /* list of allocated cards */
|
||||
/*
|
||||
==============================================================================
|
||||
*/
|
||||
static int pci_dio_insn_bits_di_b(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int pci_dio_insn_bits_di_b(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
const struct diosubd_data *d = (const struct diosubd_data *)s->private;
|
||||
int i;
|
||||
@@ -374,8 +377,9 @@ static int pci_dio_insn_bits_di_b(struct comedi_device *dev, struct comedi_subde
|
||||
/*
|
||||
==============================================================================
|
||||
*/
|
||||
static int pci_dio_insn_bits_di_w(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int pci_dio_insn_bits_di_w(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
const struct diosubd_data *d = (const struct diosubd_data *)s->private;
|
||||
int i;
|
||||
@@ -390,8 +394,9 @@ static int pci_dio_insn_bits_di_w(struct comedi_device *dev, struct comedi_subde
|
||||
/*
|
||||
==============================================================================
|
||||
*/
|
||||
static int pci_dio_insn_bits_do_b(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int pci_dio_insn_bits_do_b(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
const struct diosubd_data *d = (const struct diosubd_data *)s->private;
|
||||
int i;
|
||||
@@ -401,7 +406,7 @@ static int pci_dio_insn_bits_do_b(struct comedi_device *dev, struct comedi_subde
|
||||
s->state |= (data[0] & data[1]);
|
||||
for (i = 0; i < d->regs; i++)
|
||||
outb((s->state >> (8 * i)) & 0xff,
|
||||
dev->iobase + d->addr + i);
|
||||
dev->iobase + d->addr + i);
|
||||
}
|
||||
data[1] = s->state;
|
||||
|
||||
@@ -411,8 +416,9 @@ static int pci_dio_insn_bits_do_b(struct comedi_device *dev, struct comedi_subde
|
||||
/*
|
||||
==============================================================================
|
||||
*/
|
||||
static int pci_dio_insn_bits_do_w(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int pci_dio_insn_bits_do_w(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
const struct diosubd_data *d = (const struct diosubd_data *)s->private;
|
||||
int i;
|
||||
@@ -422,7 +428,7 @@ static int pci_dio_insn_bits_do_w(struct comedi_device *dev, struct comedi_subde
|
||||
s->state |= (data[0] & data[1]);
|
||||
for (i = 0; i < d->regs; i++)
|
||||
outw((s->state >> (16 * i)) & 0xffff,
|
||||
dev->iobase + d->addr + 2 * i);
|
||||
dev->iobase + d->addr + 2 * i);
|
||||
}
|
||||
data[1] = s->state;
|
||||
|
||||
@@ -433,7 +439,8 @@ static int pci_dio_insn_bits_do_w(struct comedi_device *dev, struct comedi_subde
|
||||
==============================================================================
|
||||
*/
|
||||
static int pci1760_unchecked_mbxrequest(struct comedi_device *dev,
|
||||
unsigned char *omb, unsigned char *imb, int repeats)
|
||||
unsigned char *omb, unsigned char *imb,
|
||||
int repeats)
|
||||
{
|
||||
int cnt, tout, ok = 0;
|
||||
|
||||
@@ -472,11 +479,11 @@ static int pci1760_clear_imb2(struct comedi_device *dev)
|
||||
}
|
||||
|
||||
static int pci1760_mbxrequest(struct comedi_device *dev,
|
||||
unsigned char *omb, unsigned char *imb)
|
||||
unsigned char *omb, unsigned char *imb)
|
||||
{
|
||||
if (omb[2] == CMD_ClearIMB2) {
|
||||
comedi_error(dev,
|
||||
"bug! this function should not be used for CMD_ClearIMB2 command");
|
||||
"bug! this function should not be used for CMD_ClearIMB2 command");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (inb(dev->iobase + IMB2) == omb[2]) {
|
||||
@@ -491,8 +498,9 @@ static int pci1760_mbxrequest(struct comedi_device *dev,
|
||||
/*
|
||||
==============================================================================
|
||||
*/
|
||||
static int pci1760_insn_bits_di(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int pci1760_insn_bits_di(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
data[1] = inb(dev->iobase + IMB3);
|
||||
|
||||
@@ -502,8 +510,9 @@ static int pci1760_insn_bits_di(struct comedi_device *dev, struct comedi_subdevi
|
||||
/*
|
||||
==============================================================================
|
||||
*/
|
||||
static int pci1760_insn_bits_do(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int pci1760_insn_bits_do(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int ret;
|
||||
unsigned char omb[4] = {
|
||||
@@ -530,8 +539,9 @@ static int pci1760_insn_bits_do(struct comedi_device *dev, struct comedi_subdevi
|
||||
/*
|
||||
==============================================================================
|
||||
*/
|
||||
static int pci1760_insn_cnt_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int pci1760_insn_cnt_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int ret, n;
|
||||
unsigned char omb[4] = {
|
||||
@@ -555,8 +565,9 @@ static int pci1760_insn_cnt_read(struct comedi_device *dev, struct comedi_subdev
|
||||
/*
|
||||
==============================================================================
|
||||
*/
|
||||
static int pci1760_insn_cnt_write(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int pci1760_insn_cnt_write(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int ret;
|
||||
unsigned char chan = CR_CHAN(insn->chanspec) & 0x07;
|
||||
@@ -570,7 +581,7 @@ static int pci1760_insn_cnt_write(struct comedi_device *dev, struct comedi_subde
|
||||
unsigned char imb[4];
|
||||
|
||||
if (devpriv->CntResValue[chan] != (data[0] & 0xffff)) { /* Set reset value if different */
|
||||
ret = pci1760_mbxrequest(dev, omb, imb);
|
||||
ret = pci1760_mbxrequest(dev, omb, imb);
|
||||
if (!ret)
|
||||
return ret;
|
||||
devpriv->CntResValue[chan] = data[0] & 0xffff;
|
||||
@@ -697,11 +708,11 @@ static int pci_dio_reset(struct comedi_device *dev)
|
||||
break;
|
||||
|
||||
case TYPE_PCI1736:
|
||||
outb(0, dev->iobase+PCI1736_IDO);
|
||||
outb(0, dev->iobase+PCI1736_IDO+1);
|
||||
outb(0, dev->iobase+PCI1736_3_INT_EN); /* disable interrupts */
|
||||
outb(0x0f, dev->iobase+PCI1736_3_INT_CLR);/* clear interrupts */
|
||||
outb(0, dev->iobase+PCI1736_3_INT_RF); /* set rising edge trigger */
|
||||
outb(0, dev->iobase + PCI1736_IDO);
|
||||
outb(0, dev->iobase + PCI1736_IDO + 1);
|
||||
outb(0, dev->iobase + PCI1736_3_INT_EN); /* disable interrupts */
|
||||
outb(0x0f, dev->iobase + PCI1736_3_INT_CLR); /* clear interrupts */
|
||||
outb(0, dev->iobase + PCI1736_3_INT_RF); /* set rising edge trigger */
|
||||
break;
|
||||
|
||||
case TYPE_PCI1750:
|
||||
@@ -756,7 +767,8 @@ static int pci_dio_reset(struct comedi_device *dev)
|
||||
/*
|
||||
==============================================================================
|
||||
*/
|
||||
static int pci1760_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
static int pci1760_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it)
|
||||
{
|
||||
struct comedi_subdevice *s;
|
||||
int subdev = 0;
|
||||
@@ -809,7 +821,7 @@ static int pci1760_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
==============================================================================
|
||||
*/
|
||||
static int pci_dio_add_di(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
const struct diosubd_data *d, int subdev)
|
||||
const struct diosubd_data *d, int subdev)
|
||||
{
|
||||
s->type = COMEDI_SUBD_DI;
|
||||
s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | d->specflags;
|
||||
@@ -836,7 +848,7 @@ static int pci_dio_add_di(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
==============================================================================
|
||||
*/
|
||||
static int pci_dio_add_do(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
const struct diosubd_data *d, int subdev)
|
||||
const struct diosubd_data *d, int subdev)
|
||||
{
|
||||
s->type = COMEDI_SUBD_DO;
|
||||
s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
|
||||
@@ -863,8 +875,9 @@ static int pci_dio_add_do(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
/*
|
||||
==============================================================================
|
||||
*/
|
||||
static int CheckAndAllocCard(struct comedi_device *dev, struct comedi_devconfig *it,
|
||||
struct pci_dev *pcidev)
|
||||
static int CheckAndAllocCard(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it,
|
||||
struct pci_dev *pcidev)
|
||||
{
|
||||
struct pci_dio_private *pr, *prev;
|
||||
|
||||
@@ -889,7 +902,8 @@ static int CheckAndAllocCard(struct comedi_device *dev, struct comedi_devconfig
|
||||
/*
|
||||
==============================================================================
|
||||
*/
|
||||
static int pci_dio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
static int pci_dio_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it)
|
||||
{
|
||||
struct comedi_subdevice *s;
|
||||
int ret, subdev, n_subdevices, i, j;
|
||||
@@ -905,8 +919,8 @@ static int pci_dio_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
}
|
||||
|
||||
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)) {
|
||||
pcidev != NULL;
|
||||
pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
|
||||
/* loop through cards supported by this driver */
|
||||
for (i = 0; i < n_boardtypes; ++i) {
|
||||
if (boardtypes[i].vendor_id != pcidev->vendor)
|
||||
@@ -917,13 +931,13 @@ static int pci_dio_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
if (it->options[0] || it->options[1]) {
|
||||
/* are we on the wrong bus/slot? */
|
||||
if (pcidev->bus->number != it->options[0] ||
|
||||
PCI_SLOT(pcidev->devfn) !=
|
||||
it->options[1]) {
|
||||
PCI_SLOT(pcidev->devfn) != it->options[1]) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
ret = CheckAndAllocCard(dev, it, pcidev);
|
||||
if (ret != 1) continue;
|
||||
if (ret != 1)
|
||||
continue;
|
||||
dev->board_ptr = boardtypes + i;
|
||||
break;
|
||||
}
|
||||
@@ -932,20 +946,19 @@ static int pci_dio_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
}
|
||||
|
||||
if (!dev->board_ptr) {
|
||||
printk
|
||||
(", Error: Requested type of the card was not found!\n");
|
||||
printk(", Error: Requested type of the card was not found!\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (comedi_pci_enable(pcidev, driver_pci_dio.driver_name)) {
|
||||
printk
|
||||
(", Error: Can't enable PCI device and request regions!\n");
|
||||
(", Error: Can't enable PCI device and request regions!\n");
|
||||
return -EIO;
|
||||
}
|
||||
iobase = pci_resource_start(pcidev, this_board->main_pci_region);
|
||||
printk(", b:s:f=%d:%d:%d, io=0x%4lx",
|
||||
pcidev->bus->number, PCI_SLOT(pcidev->devfn),
|
||||
PCI_FUNC(pcidev->devfn), iobase);
|
||||
pcidev->bus->number, PCI_SLOT(pcidev->devfn),
|
||||
PCI_FUNC(pcidev->devfn), iobase);
|
||||
|
||||
dev->iobase = iobase;
|
||||
dev->board_name = this_board->name;
|
||||
@@ -994,8 +1007,9 @@ static int pci_dio_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
for (j = 0; j < this_board->sdio[i].regs; j++) {
|
||||
s = dev->subdevices + subdev;
|
||||
subdev_8255_init(dev, s, NULL,
|
||||
dev->iobase + this_board->sdio[i].addr +
|
||||
SIZE_8255 * j);
|
||||
dev->iobase +
|
||||
this_board->sdio[i].addr +
|
||||
SIZE_8255 * j);
|
||||
subdev++;
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ struct aio12_8_boardtype {
|
||||
|
||||
static const struct aio12_8_boardtype board_types[] = {
|
||||
{
|
||||
.name = "aio_aio12_8"},
|
||||
.name = "aio_aio12_8"},
|
||||
};
|
||||
|
||||
#define thisboard ((const struct aio12_8_boardtype *) dev->board_ptr)
|
||||
@@ -88,13 +88,14 @@ struct aio12_8_private {
|
||||
|
||||
#define devpriv ((struct aio12_8_private *) dev->private)
|
||||
|
||||
static int aio_aio12_8_ai_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int aio_aio12_8_ai_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int n;
|
||||
unsigned char control =
|
||||
ADC_MODE_NORMAL |
|
||||
(CR_RANGE(insn->chanspec) << 3) | CR_CHAN(insn->chanspec);
|
||||
ADC_MODE_NORMAL |
|
||||
(CR_RANGE(insn->chanspec) << 3) | CR_CHAN(insn->chanspec);
|
||||
|
||||
/* read status to clear EOC latch */
|
||||
inb(dev->iobase + AIO12_8_STATUS);
|
||||
@@ -107,7 +108,7 @@ static int aio_aio12_8_ai_read(struct comedi_device *dev, struct comedi_subdevic
|
||||
|
||||
/* Wait for conversion to complete */
|
||||
while (timeout &&
|
||||
!(inb(dev->iobase + AIO12_8_STATUS) & STATUS_ADC_EOC)) {
|
||||
!(inb(dev->iobase + AIO12_8_STATUS) & STATUS_ADC_EOC)) {
|
||||
timeout--;
|
||||
printk("timeout %d\n", timeout);
|
||||
udelay(1);
|
||||
@@ -122,8 +123,9 @@ static int aio_aio12_8_ai_read(struct comedi_device *dev, struct comedi_subdevic
|
||||
return n;
|
||||
}
|
||||
|
||||
static int aio_aio12_8_ao_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int aio_aio12_8_ao_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int i;
|
||||
int val = devpriv->ao_readback[CR_CHAN(insn->chanspec)];
|
||||
@@ -133,8 +135,9 @@ static int aio_aio12_8_ao_read(struct comedi_device *dev, struct comedi_subdevic
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
static int aio_aio12_8_ao_write(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int aio_aio12_8_ao_write(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int i;
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
@@ -154,14 +157,15 @@ static int aio_aio12_8_ao_write(struct comedi_device *dev, struct comedi_subdevi
|
||||
static const struct comedi_lrange range_aio_aio12_8 = {
|
||||
4,
|
||||
{
|
||||
UNI_RANGE(5),
|
||||
BIP_RANGE(5),
|
||||
UNI_RANGE(10),
|
||||
BIP_RANGE(10),
|
||||
}
|
||||
UNI_RANGE(5),
|
||||
BIP_RANGE(5),
|
||||
UNI_RANGE(10),
|
||||
BIP_RANGE(10),
|
||||
}
|
||||
};
|
||||
|
||||
static int aio_aio12_8_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
static int aio_aio12_8_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it)
|
||||
{
|
||||
int iobase;
|
||||
struct comedi_subdevice *s;
|
||||
|
||||
@@ -52,9 +52,9 @@ struct aio_iiro_16_board {
|
||||
|
||||
static const struct aio_iiro_16_board aio_iiro_16_boards[] = {
|
||||
{
|
||||
.name = "aio_iiro_16",
|
||||
.di = 16,
|
||||
.do_ = 16},
|
||||
.name = "aio_iiro_16",
|
||||
.di = 16,
|
||||
.do_ = 16},
|
||||
};
|
||||
|
||||
#define thisboard ((const struct aio_iiro_16_board *) dev->board_ptr)
|
||||
@@ -67,7 +67,8 @@ struct aio_iiro_16_private {
|
||||
|
||||
#define devpriv ((struct aio_iiro_16_private *) dev->private)
|
||||
|
||||
static int aio_iiro_16_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int aio_iiro_16_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
|
||||
static int aio_iiro_16_detach(struct comedi_device *dev);
|
||||
|
||||
@@ -82,12 +83,17 @@ static struct comedi_driver driver_aio_iiro_16 = {
|
||||
};
|
||||
|
||||
static int aio_iiro_16_dio_insn_bits_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
|
||||
static int aio_iiro_16_dio_insn_bits_write(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
|
||||
static int aio_iiro_16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
static int aio_iiro_16_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it)
|
||||
{
|
||||
int iobase;
|
||||
struct comedi_subdevice *s;
|
||||
@@ -143,7 +149,9 @@ static int aio_iiro_16_detach(struct comedi_device *dev)
|
||||
}
|
||||
|
||||
static int aio_iiro_16_dio_insn_bits_write(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
if (insn->n != 2)
|
||||
return -EINVAL;
|
||||
@@ -153,7 +161,7 @@ static int aio_iiro_16_dio_insn_bits_write(struct comedi_device *dev,
|
||||
s->state |= data[0] & data[1];
|
||||
outb(s->state & 0xff, dev->iobase + AIO_IIRO_16_RELAY_0_7);
|
||||
outb((s->state >> 8) & 0xff,
|
||||
dev->iobase + AIO_IIRO_16_RELAY_8_15);
|
||||
dev->iobase + AIO_IIRO_16_RELAY_8_15);
|
||||
}
|
||||
|
||||
data[1] = s->state;
|
||||
@@ -162,7 +170,9 @@ static int aio_iiro_16_dio_insn_bits_write(struct comedi_device *dev,
|
||||
}
|
||||
|
||||
static int aio_iiro_16_dio_insn_bits_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
if (insn->n != 2)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -290,60 +290,60 @@ struct dio200_board {
|
||||
|
||||
static const struct dio200_board dio200_boards[] = {
|
||||
{
|
||||
.name = "pc212e",
|
||||
.bustype = isa_bustype,
|
||||
.model = pc212e_model,
|
||||
.layout = pc212_layout,
|
||||
},
|
||||
.name = "pc212e",
|
||||
.bustype = isa_bustype,
|
||||
.model = pc212e_model,
|
||||
.layout = pc212_layout,
|
||||
},
|
||||
{
|
||||
.name = "pc214e",
|
||||
.bustype = isa_bustype,
|
||||
.model = pc214e_model,
|
||||
.layout = pc214_layout,
|
||||
},
|
||||
.name = "pc214e",
|
||||
.bustype = isa_bustype,
|
||||
.model = pc214e_model,
|
||||
.layout = pc214_layout,
|
||||
},
|
||||
{
|
||||
.name = "pc215e",
|
||||
.bustype = isa_bustype,
|
||||
.model = pc215e_model,
|
||||
.layout = pc215_layout,
|
||||
},
|
||||
.name = "pc215e",
|
||||
.bustype = isa_bustype,
|
||||
.model = pc215e_model,
|
||||
.layout = pc215_layout,
|
||||
},
|
||||
#ifdef CONFIG_COMEDI_PCI
|
||||
{
|
||||
.name = "pci215",
|
||||
.devid = PCI_DEVICE_ID_AMPLICON_PCI215,
|
||||
.bustype = pci_bustype,
|
||||
.model = pci215_model,
|
||||
.layout = pc215_layout,
|
||||
},
|
||||
.name = "pci215",
|
||||
.devid = PCI_DEVICE_ID_AMPLICON_PCI215,
|
||||
.bustype = pci_bustype,
|
||||
.model = pci215_model,
|
||||
.layout = pc215_layout,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
.name = "pc218e",
|
||||
.bustype = isa_bustype,
|
||||
.model = pc218e_model,
|
||||
.layout = pc218_layout,
|
||||
},
|
||||
.name = "pc218e",
|
||||
.bustype = isa_bustype,
|
||||
.model = pc218e_model,
|
||||
.layout = pc218_layout,
|
||||
},
|
||||
{
|
||||
.name = "pc272e",
|
||||
.bustype = isa_bustype,
|
||||
.model = pc272e_model,
|
||||
.layout = pc272_layout,
|
||||
},
|
||||
.name = "pc272e",
|
||||
.bustype = isa_bustype,
|
||||
.model = pc272e_model,
|
||||
.layout = pc272_layout,
|
||||
},
|
||||
#ifdef CONFIG_COMEDI_PCI
|
||||
{
|
||||
.name = "pci272",
|
||||
.devid = PCI_DEVICE_ID_AMPLICON_PCI272,
|
||||
.bustype = pci_bustype,
|
||||
.model = pci272_model,
|
||||
.layout = pc272_layout,
|
||||
},
|
||||
.name = "pci272",
|
||||
.devid = PCI_DEVICE_ID_AMPLICON_PCI272,
|
||||
.bustype = pci_bustype,
|
||||
.model = pci272_model,
|
||||
.layout = pc272_layout,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_COMEDI_PCI
|
||||
{
|
||||
.name = DIO200_DRIVER_NAME,
|
||||
.devid = PCI_DEVICE_ID_INVALID,
|
||||
.bustype = pci_bustype,
|
||||
.model = anypci_model, /* wildcard */
|
||||
},
|
||||
.name = DIO200_DRIVER_NAME,
|
||||
.devid = PCI_DEVICE_ID_INVALID,
|
||||
.bustype = pci_bustype,
|
||||
.model = anypci_model, /* wildcard */
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -367,51 +367,51 @@ struct dio200_layout_struct {
|
||||
|
||||
static const struct dio200_layout_struct dio200_layouts[] = {
|
||||
[pc212_layout] = {
|
||||
.n_subdevs = 6,
|
||||
.sdtype = {sd_8255, sd_8254, sd_8254, sd_8254,
|
||||
sd_8254,
|
||||
sd_intr},
|
||||
.sdinfo = {0x00, 0x08, 0x0C, 0x10, 0x14,
|
||||
0x3F},
|
||||
.has_int_sce = 1,
|
||||
.has_clk_gat_sce = 1,
|
||||
},
|
||||
.n_subdevs = 6,
|
||||
.sdtype = {sd_8255, sd_8254, sd_8254, sd_8254,
|
||||
sd_8254,
|
||||
sd_intr},
|
||||
.sdinfo = {0x00, 0x08, 0x0C, 0x10, 0x14,
|
||||
0x3F},
|
||||
.has_int_sce = 1,
|
||||
.has_clk_gat_sce = 1,
|
||||
},
|
||||
[pc214_layout] = {
|
||||
.n_subdevs = 4,
|
||||
.sdtype = {sd_8255, sd_8255, sd_8254,
|
||||
sd_intr},
|
||||
.sdinfo = {0x00, 0x08, 0x10, 0x01},
|
||||
.has_int_sce = 0,
|
||||
.has_clk_gat_sce = 0,
|
||||
},
|
||||
.n_subdevs = 4,
|
||||
.sdtype = {sd_8255, sd_8255, sd_8254,
|
||||
sd_intr},
|
||||
.sdinfo = {0x00, 0x08, 0x10, 0x01},
|
||||
.has_int_sce = 0,
|
||||
.has_clk_gat_sce = 0,
|
||||
},
|
||||
[pc215_layout] = {
|
||||
.n_subdevs = 5,
|
||||
.sdtype = {sd_8255, sd_8255, sd_8254,
|
||||
sd_8254,
|
||||
sd_intr},
|
||||
.sdinfo = {0x00, 0x08, 0x10, 0x14, 0x3F},
|
||||
.has_int_sce = 1,
|
||||
.has_clk_gat_sce = 1,
|
||||
},
|
||||
.n_subdevs = 5,
|
||||
.sdtype = {sd_8255, sd_8255, sd_8254,
|
||||
sd_8254,
|
||||
sd_intr},
|
||||
.sdinfo = {0x00, 0x08, 0x10, 0x14, 0x3F},
|
||||
.has_int_sce = 1,
|
||||
.has_clk_gat_sce = 1,
|
||||
},
|
||||
[pc218_layout] = {
|
||||
.n_subdevs = 7,
|
||||
.sdtype = {sd_8254, sd_8254, sd_8255, sd_8254,
|
||||
sd_8254,
|
||||
sd_intr},
|
||||
.sdinfo = {0x00, 0x04, 0x08, 0x0C, 0x10,
|
||||
0x14,
|
||||
0x3F},
|
||||
.has_int_sce = 1,
|
||||
.has_clk_gat_sce = 1,
|
||||
},
|
||||
.n_subdevs = 7,
|
||||
.sdtype = {sd_8254, sd_8254, sd_8255, sd_8254,
|
||||
sd_8254,
|
||||
sd_intr},
|
||||
.sdinfo = {0x00, 0x04, 0x08, 0x0C, 0x10,
|
||||
0x14,
|
||||
0x3F},
|
||||
.has_int_sce = 1,
|
||||
.has_clk_gat_sce = 1,
|
||||
},
|
||||
[pc272_layout] = {
|
||||
.n_subdevs = 4,
|
||||
.sdtype = {sd_8255, sd_8255, sd_8255,
|
||||
sd_intr},
|
||||
.sdinfo = {0x00, 0x08, 0x10, 0x3F},
|
||||
.has_int_sce = 1,
|
||||
.has_clk_gat_sce = 0,
|
||||
},
|
||||
.n_subdevs = 4,
|
||||
.sdtype = {sd_8255, sd_8255, sd_8255,
|
||||
sd_intr},
|
||||
.sdinfo = {0x00, 0x08, 0x10, 0x3F},
|
||||
.has_int_sce = 1,
|
||||
.has_clk_gat_sce = 0,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -420,11 +420,12 @@ static const struct dio200_layout_struct dio200_layouts[] = {
|
||||
|
||||
#ifdef CONFIG_COMEDI_PCI
|
||||
static DEFINE_PCI_DEVICE_TABLE(dio200_pci_table) = {
|
||||
{PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI215,
|
||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI272,
|
||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{0}
|
||||
{
|
||||
PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI215,
|
||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI272,
|
||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
0}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, dio200_pci_table);
|
||||
@@ -475,7 +476,8 @@ struct dio200_subdev_intr {
|
||||
* the board, and also about the kernel module that contains
|
||||
* the device code.
|
||||
*/
|
||||
static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int dio200_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int dio200_detach(struct comedi_device *dev);
|
||||
static struct comedi_driver driver_amplc_dio200 = {
|
||||
.driver_name = DIO200_DRIVER_NAME,
|
||||
@@ -500,7 +502,7 @@ COMEDI_INITCLEANUP(driver_amplc_dio200);
|
||||
#ifdef CONFIG_COMEDI_PCI
|
||||
static int
|
||||
dio200_find_pci(struct comedi_device *dev, int bus, int slot,
|
||||
struct pci_dev **pci_dev_p)
|
||||
struct pci_dev **pci_dev_p)
|
||||
{
|
||||
struct pci_dev *pci_dev = NULL;
|
||||
|
||||
@@ -508,13 +510,13 @@ dio200_find_pci(struct comedi_device *dev, int bus, int slot,
|
||||
|
||||
/* Look for matching PCI device. */
|
||||
for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL);
|
||||
pci_dev != NULL;
|
||||
pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON,
|
||||
PCI_ANY_ID, pci_dev)) {
|
||||
pci_dev != NULL;
|
||||
pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON,
|
||||
PCI_ANY_ID, pci_dev)) {
|
||||
/* If bus/slot specified, check them. */
|
||||
if (bus || slot) {
|
||||
if (bus != pci_dev->bus->number
|
||||
|| slot != PCI_SLOT(pci_dev->devfn))
|
||||
|| slot != PCI_SLOT(pci_dev->devfn))
|
||||
continue;
|
||||
}
|
||||
if (thisboard->model == anypci_model) {
|
||||
@@ -545,11 +547,11 @@ dio200_find_pci(struct comedi_device *dev, int bus, int slot,
|
||||
/* No match found. */
|
||||
if (bus || slot) {
|
||||
printk(KERN_ERR
|
||||
"comedi%d: error! no %s found at pci %02x:%02x!\n",
|
||||
dev->minor, thisboard->name, bus, slot);
|
||||
"comedi%d: error! no %s found at pci %02x:%02x!\n",
|
||||
dev->minor, thisboard->name, bus, slot);
|
||||
} else {
|
||||
printk(KERN_ERR "comedi%d: error! no %s found!\n",
|
||||
dev->minor, thisboard->name);
|
||||
dev->minor, thisboard->name);
|
||||
}
|
||||
return -EIO;
|
||||
}
|
||||
@@ -564,7 +566,7 @@ dio200_request_region(unsigned minor, unsigned long from, unsigned long extent)
|
||||
{
|
||||
if (!from || !request_region(from, extent, DIO200_DRIVER_NAME)) {
|
||||
printk(KERN_ERR "comedi%d: I/O port conflict (%#lx,%lu)!\n",
|
||||
minor, from, extent);
|
||||
minor, from, extent);
|
||||
return -EIO;
|
||||
}
|
||||
return 0;
|
||||
@@ -574,8 +576,9 @@ dio200_request_region(unsigned minor, unsigned long from, unsigned long extent)
|
||||
* 'insn_bits' function for an 'INTERRUPT' subdevice.
|
||||
*/
|
||||
static int
|
||||
dio200_subdev_intr_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
dio200_subdev_intr_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
struct dio200_subdev_intr *subpriv = s->private;
|
||||
|
||||
@@ -593,7 +596,8 @@ dio200_subdev_intr_insn_bits(struct comedi_device *dev, struct comedi_subdevice
|
||||
/*
|
||||
* Called to stop acquisition for an 'INTERRUPT' subdevice.
|
||||
*/
|
||||
static void dio200_stop_intr(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
static void dio200_stop_intr(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
struct dio200_subdev_intr *subpriv = s->private;
|
||||
|
||||
@@ -607,7 +611,8 @@ static void dio200_stop_intr(struct comedi_device *dev, struct comedi_subdevice
|
||||
/*
|
||||
* Called to start acquisition for an 'INTERRUPT' subdevice.
|
||||
*/
|
||||
static int dio200_start_intr(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
static int dio200_start_intr(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
unsigned int n;
|
||||
unsigned isn_bits;
|
||||
@@ -644,7 +649,7 @@ static int dio200_start_intr(struct comedi_device *dev, struct comedi_subdevice
|
||||
*/
|
||||
static int
|
||||
dio200_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
unsigned int trignum)
|
||||
unsigned int trignum)
|
||||
{
|
||||
struct dio200_subdev_intr *subpriv;
|
||||
unsigned long flags;
|
||||
@@ -673,7 +678,8 @@ dio200_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
* This is called from the interrupt service routine to handle a read
|
||||
* scan on an 'INTERRUPT' subdevice.
|
||||
*/
|
||||
static int dio200_handle_read_intr(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
static int dio200_handle_read_intr(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
struct dio200_subdev_intr *subpriv = s->private;
|
||||
unsigned triggered;
|
||||
@@ -699,7 +705,7 @@ static int dio200_handle_read_intr(struct comedi_device *dev, struct comedi_subd
|
||||
*/
|
||||
cur_enabled = subpriv->enabled_isns;
|
||||
while ((intstat = (inb(subpriv->iobase) & subpriv->valid_isns
|
||||
& ~triggered)) != 0) {
|
||||
& ~triggered)) != 0) {
|
||||
triggered |= intstat;
|
||||
cur_enabled &= ~triggered;
|
||||
outb(cur_enabled, subpriv->iobase);
|
||||
@@ -748,12 +754,12 @@ static int dio200_handle_read_intr(struct comedi_device *dev, struct comedi_subd
|
||||
/* Write the scan to the buffer. */
|
||||
if (comedi_buf_put(s->async, val)) {
|
||||
s->async->events |= (COMEDI_CB_BLOCK |
|
||||
COMEDI_CB_EOS);
|
||||
COMEDI_CB_EOS);
|
||||
} else {
|
||||
/* Error! Stop acquisition. */
|
||||
dio200_stop_intr(dev, s);
|
||||
s->async->events |= COMEDI_CB_ERROR
|
||||
| COMEDI_CB_OVERFLOW;
|
||||
| COMEDI_CB_OVERFLOW;
|
||||
comedi_error(dev, "buffer overflow");
|
||||
}
|
||||
|
||||
@@ -764,9 +770,9 @@ static int dio200_handle_read_intr(struct comedi_device *dev, struct comedi_subd
|
||||
subpriv->stopcount--;
|
||||
if (subpriv->stopcount == 0) {
|
||||
s->async->events |=
|
||||
COMEDI_CB_EOA;
|
||||
COMEDI_CB_EOA;
|
||||
dio200_stop_intr(dev,
|
||||
s);
|
||||
s);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -785,7 +791,8 @@ static int dio200_handle_read_intr(struct comedi_device *dev, struct comedi_subd
|
||||
/*
|
||||
* 'cancel' function for an 'INTERRUPT' subdevice.
|
||||
*/
|
||||
static int dio200_subdev_intr_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
static int dio200_subdev_intr_cancel(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
struct dio200_subdev_intr *subpriv = s->private;
|
||||
unsigned long flags;
|
||||
@@ -803,8 +810,8 @@ static int dio200_subdev_intr_cancel(struct comedi_device *dev, struct comedi_su
|
||||
* 'do_cmdtest' function for an 'INTERRUPT' subdevice.
|
||||
*/
|
||||
static int
|
||||
dio200_subdev_intr_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd)
|
||||
dio200_subdev_intr_cmdtest(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_cmd *cmd)
|
||||
{
|
||||
int err = 0;
|
||||
unsigned int tmp;
|
||||
@@ -909,7 +916,8 @@ dio200_subdev_intr_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s
|
||||
/*
|
||||
* 'do_cmd' function for an 'INTERRUPT' subdevice.
|
||||
*/
|
||||
static int dio200_subdev_intr_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
static int dio200_subdev_intr_cmd(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
struct comedi_cmd *cmd = &s->async->cmd;
|
||||
struct dio200_subdev_intr *subpriv = s->private;
|
||||
@@ -956,14 +964,15 @@ static int dio200_subdev_intr_cmd(struct comedi_device *dev, struct comedi_subde
|
||||
*/
|
||||
static int
|
||||
dio200_subdev_intr_init(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
unsigned long iobase, unsigned valid_isns, int has_int_sce)
|
||||
unsigned long iobase, unsigned valid_isns,
|
||||
int has_int_sce)
|
||||
{
|
||||
struct dio200_subdev_intr *subpriv;
|
||||
|
||||
subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
|
||||
if (!subpriv) {
|
||||
printk(KERN_ERR "comedi%d: error! out of memory!\n",
|
||||
dev->minor);
|
||||
dev->minor);
|
||||
return -ENOMEM;
|
||||
}
|
||||
subpriv->iobase = iobase;
|
||||
@@ -1000,7 +1009,8 @@ dio200_subdev_intr_init(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
* This function cleans up an 'INTERRUPT' subdevice.
|
||||
*/
|
||||
static void
|
||||
dio200_subdev_intr_cleanup(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
dio200_subdev_intr_cleanup(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
struct dio200_subdev_intr *subpriv = s->private;
|
||||
|
||||
@@ -1023,7 +1033,8 @@ static irqreturn_t dio200_interrupt(int irq, void *d)
|
||||
|
||||
if (devpriv->intr_sd >= 0) {
|
||||
handled = dio200_handle_read_intr(dev,
|
||||
dev->subdevices + devpriv->intr_sd);
|
||||
dev->subdevices +
|
||||
devpriv->intr_sd);
|
||||
} else {
|
||||
handled = 0;
|
||||
}
|
||||
@@ -1036,7 +1047,7 @@ static irqreturn_t dio200_interrupt(int irq, void *d)
|
||||
*/
|
||||
static int
|
||||
dio200_subdev_8254_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
struct dio200_subdev_8254 *subpriv = s->private;
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
@@ -1051,7 +1062,7 @@ dio200_subdev_8254_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
*/
|
||||
static int
|
||||
dio200_subdev_8254_write(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
struct dio200_subdev_8254 *subpriv = s->private;
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
@@ -1065,8 +1076,8 @@ dio200_subdev_8254_write(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
* Set gate source for an '8254' counter subdevice channel.
|
||||
*/
|
||||
static int
|
||||
dio200_set_gate_src(struct dio200_subdev_8254 *subpriv, unsigned int counter_number,
|
||||
unsigned int gate_src)
|
||||
dio200_set_gate_src(struct dio200_subdev_8254 *subpriv,
|
||||
unsigned int counter_number, unsigned int gate_src)
|
||||
{
|
||||
unsigned char byte;
|
||||
|
||||
@@ -1088,7 +1099,8 @@ dio200_set_gate_src(struct dio200_subdev_8254 *subpriv, unsigned int counter_num
|
||||
* Get gate source for an '8254' counter subdevice channel.
|
||||
*/
|
||||
static int
|
||||
dio200_get_gate_src(struct dio200_subdev_8254 *subpriv, unsigned int counter_number)
|
||||
dio200_get_gate_src(struct dio200_subdev_8254 *subpriv,
|
||||
unsigned int counter_number)
|
||||
{
|
||||
if (!subpriv->has_clk_gat_sce)
|
||||
return -1;
|
||||
@@ -1102,8 +1114,8 @@ dio200_get_gate_src(struct dio200_subdev_8254 *subpriv, unsigned int counter_num
|
||||
* Set clock source for an '8254' counter subdevice channel.
|
||||
*/
|
||||
static int
|
||||
dio200_set_clock_src(struct dio200_subdev_8254 *subpriv, unsigned int counter_number,
|
||||
unsigned int clock_src)
|
||||
dio200_set_clock_src(struct dio200_subdev_8254 *subpriv,
|
||||
unsigned int counter_number, unsigned int clock_src)
|
||||
{
|
||||
unsigned char byte;
|
||||
|
||||
@@ -1125,8 +1137,8 @@ dio200_set_clock_src(struct dio200_subdev_8254 *subpriv, unsigned int counter_nu
|
||||
* Get clock source for an '8254' counter subdevice channel.
|
||||
*/
|
||||
static int
|
||||
dio200_get_clock_src(struct dio200_subdev_8254 *subpriv, unsigned int counter_number,
|
||||
unsigned int *period_ns)
|
||||
dio200_get_clock_src(struct dio200_subdev_8254 *subpriv,
|
||||
unsigned int counter_number, unsigned int *period_ns)
|
||||
{
|
||||
unsigned clock_src;
|
||||
|
||||
@@ -1145,7 +1157,7 @@ dio200_get_clock_src(struct dio200_subdev_8254 *subpriv, unsigned int counter_nu
|
||||
*/
|
||||
static int
|
||||
dio200_subdev_8254_config(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
struct dio200_subdev_8254 *subpriv = s->private;
|
||||
int ret;
|
||||
@@ -1197,7 +1209,8 @@ dio200_subdev_8254_config(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
*/
|
||||
static int
|
||||
dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
unsigned long iobase, unsigned offset, int has_clk_gat_sce)
|
||||
unsigned long iobase, unsigned offset,
|
||||
int has_clk_gat_sce)
|
||||
{
|
||||
struct dio200_subdev_8254 *subpriv;
|
||||
unsigned int chan;
|
||||
@@ -1205,7 +1218,7 @@ dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
|
||||
if (!subpriv) {
|
||||
printk(KERN_ERR "comedi%d: error! out of memory!\n",
|
||||
dev->minor);
|
||||
dev->minor);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@@ -1224,16 +1237,16 @@ dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
/* Derive CLK_SCE and GAT_SCE register offsets from
|
||||
* 8254 offset. */
|
||||
subpriv->clk_sce_iobase =
|
||||
DIO200_XCLK_SCE + (offset >> 3) + iobase;
|
||||
DIO200_XCLK_SCE + (offset >> 3) + iobase;
|
||||
subpriv->gat_sce_iobase =
|
||||
DIO200_XGAT_SCE + (offset >> 3) + iobase;
|
||||
DIO200_XGAT_SCE + (offset >> 3) + iobase;
|
||||
subpriv->which = (offset >> 2) & 1;
|
||||
}
|
||||
|
||||
/* Initialize channels. */
|
||||
for (chan = 0; chan < 3; chan++) {
|
||||
i8254_set_mode(subpriv->iobase, 0, chan,
|
||||
I8254_MODE0 | I8254_BINARY);
|
||||
I8254_MODE0 | I8254_BINARY);
|
||||
if (subpriv->has_clk_gat_sce) {
|
||||
/* Gate source 0 is VCC (logic 1). */
|
||||
dio200_set_gate_src(subpriv, chan, 0);
|
||||
@@ -1249,7 +1262,8 @@ dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
* This function cleans up an '8254' counter subdevice.
|
||||
*/
|
||||
static void
|
||||
dio200_subdev_8254_cleanup(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
dio200_subdev_8254_cleanup(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
struct dio200_subdev_intr *subpriv = s->private;
|
||||
|
||||
@@ -1280,12 +1294,12 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
int ret;
|
||||
|
||||
printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor,
|
||||
DIO200_DRIVER_NAME);
|
||||
DIO200_DRIVER_NAME);
|
||||
|
||||
ret = alloc_private(dev, sizeof(struct dio200_private));
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "comedi%d: error! out of memory!\n",
|
||||
dev->minor);
|
||||
dev->minor);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1310,8 +1324,8 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
#endif
|
||||
default:
|
||||
printk(KERN_ERR
|
||||
"comedi%d: %s: BUG! cannot determine board type!\n",
|
||||
dev->minor, DIO200_DRIVER_NAME);
|
||||
"comedi%d: %s: BUG! cannot determine board type!\n",
|
||||
dev->minor, DIO200_DRIVER_NAME);
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
@@ -1324,8 +1338,8 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
ret = comedi_pci_enable(pci_dev, DIO200_DRIVER_NAME);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR
|
||||
"comedi%d: error! cannot enable PCI device and request regions!\n",
|
||||
dev->minor);
|
||||
"comedi%d: error! cannot enable PCI device and request regions!\n",
|
||||
dev->minor);
|
||||
return ret;
|
||||
}
|
||||
iobase = pci_resource_start(pci_dev, 2);
|
||||
@@ -1345,7 +1359,7 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
ret = alloc_subdevices(dev, layout->n_subdevs);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "comedi%d: error! out of memory!\n",
|
||||
dev->minor);
|
||||
dev->minor);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1355,7 +1369,8 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
case sd_8254:
|
||||
/* counter subdevice (8254) */
|
||||
ret = dio200_subdev_8254_init(dev, s, iobase,
|
||||
layout->sdinfo[n], layout->has_clk_gat_sce);
|
||||
layout->sdinfo[n],
|
||||
layout->has_clk_gat_sce);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
@@ -1363,7 +1378,7 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
case sd_8255:
|
||||
/* digital i/o subdevice (8255) */
|
||||
ret = subdev_8255_init(dev, s, 0,
|
||||
iobase + layout->sdinfo[n]);
|
||||
iobase + layout->sdinfo[n]);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
@@ -1372,8 +1387,11 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
/* 'INTERRUPT' subdevice */
|
||||
if (irq) {
|
||||
ret = dio200_subdev_intr_init(dev, s,
|
||||
iobase + DIO200_INT_SCE,
|
||||
layout->sdinfo[n], layout->has_int_sce);
|
||||
iobase +
|
||||
DIO200_INT_SCE,
|
||||
layout->sdinfo[n],
|
||||
layout->
|
||||
has_int_sce);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
@@ -1403,8 +1421,8 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
dev->irq = irq;
|
||||
} else {
|
||||
printk(KERN_WARNING
|
||||
"comedi%d: warning! irq %u unavailable!\n",
|
||||
dev->minor, irq);
|
||||
"comedi%d: warning! irq %u unavailable!\n",
|
||||
dev->minor, irq);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1441,7 +1459,7 @@ static int dio200_detach(struct comedi_device *dev)
|
||||
unsigned n;
|
||||
|
||||
printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
|
||||
DIO200_DRIVER_NAME);
|
||||
DIO200_DRIVER_NAME);
|
||||
|
||||
if (dev->irq) {
|
||||
free_irq(dev->irq, dev);
|
||||
@@ -1482,7 +1500,7 @@ static int dio200_detach(struct comedi_device *dev)
|
||||
}
|
||||
if (dev->board_name) {
|
||||
printk(KERN_INFO "comedi%d: %s removed\n",
|
||||
dev->minor, dev->board_name);
|
||||
dev->minor, dev->board_name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -107,36 +107,37 @@ struct pc236_board {
|
||||
};
|
||||
static const struct pc236_board pc236_boards[] = {
|
||||
{
|
||||
.name = "pc36at",
|
||||
.fancy_name = "PC36AT",
|
||||
.bustype = isa_bustype,
|
||||
.model = pc36at_model,
|
||||
},
|
||||
.name = "pc36at",
|
||||
.fancy_name = "PC36AT",
|
||||
.bustype = isa_bustype,
|
||||
.model = pc36at_model,
|
||||
},
|
||||
#ifdef CONFIG_COMEDI_PCI
|
||||
{
|
||||
.name = "pci236",
|
||||
.fancy_name = "PCI236",
|
||||
.devid = PCI_DEVICE_ID_AMPLICON_PCI236,
|
||||
.bustype = pci_bustype,
|
||||
.model = pci236_model,
|
||||
},
|
||||
.name = "pci236",
|
||||
.fancy_name = "PCI236",
|
||||
.devid = PCI_DEVICE_ID_AMPLICON_PCI236,
|
||||
.bustype = pci_bustype,
|
||||
.model = pci236_model,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_COMEDI_PCI
|
||||
{
|
||||
.name = PC236_DRIVER_NAME,
|
||||
.fancy_name = PC236_DRIVER_NAME,
|
||||
.devid = PCI_DEVICE_ID_INVALID,
|
||||
.bustype = pci_bustype,
|
||||
.model = anypci_model, /* wildcard */
|
||||
},
|
||||
.name = PC236_DRIVER_NAME,
|
||||
.fancy_name = PC236_DRIVER_NAME,
|
||||
.devid = PCI_DEVICE_ID_INVALID,
|
||||
.bustype = pci_bustype,
|
||||
.model = anypci_model, /* wildcard */
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef CONFIG_COMEDI_PCI
|
||||
static DEFINE_PCI_DEVICE_TABLE(pc236_pci_table) = {
|
||||
{PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI236, PCI_ANY_ID,
|
||||
PCI_ANY_ID, 0, 0, 0},
|
||||
{0}
|
||||
{
|
||||
PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI236,
|
||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
0}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, pc236_pci_table);
|
||||
@@ -186,16 +187,20 @@ COMEDI_INITCLEANUP(driver_amplc_pc236);
|
||||
#endif
|
||||
|
||||
static int pc236_request_region(unsigned minor, unsigned long from,
|
||||
unsigned long extent);
|
||||
unsigned long extent);
|
||||
static void pc236_intr_disable(struct comedi_device *dev);
|
||||
static void pc236_intr_enable(struct comedi_device *dev);
|
||||
static int pc236_intr_check(struct comedi_device *dev);
|
||||
static int pc236_intr_insn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int pc236_intr_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd);
|
||||
static int pc236_intr_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
|
||||
static int pc236_intr_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
|
||||
static int pc236_intr_insn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
static int pc236_intr_cmdtest(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd);
|
||||
static int pc236_intr_cmd(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s);
|
||||
static int pc236_intr_cancel(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s);
|
||||
static irqreturn_t pc236_interrupt(int irq, void *d);
|
||||
|
||||
/*
|
||||
@@ -205,7 +210,7 @@ static irqreturn_t pc236_interrupt(int irq, void *d);
|
||||
#ifdef CONFIG_COMEDI_PCI
|
||||
static int
|
||||
pc236_find_pci(struct comedi_device *dev, int bus, int slot,
|
||||
struct pci_dev **pci_dev_p)
|
||||
struct pci_dev **pci_dev_p)
|
||||
{
|
||||
struct pci_dev *pci_dev = NULL;
|
||||
|
||||
@@ -213,13 +218,13 @@ pc236_find_pci(struct comedi_device *dev, int bus, int slot,
|
||||
|
||||
/* Look for matching PCI device. */
|
||||
for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL);
|
||||
pci_dev != NULL;
|
||||
pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON,
|
||||
PCI_ANY_ID, pci_dev)) {
|
||||
pci_dev != NULL;
|
||||
pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON,
|
||||
PCI_ANY_ID, pci_dev)) {
|
||||
/* If bus/slot specified, check them. */
|
||||
if (bus || slot) {
|
||||
if (bus != pci_dev->bus->number
|
||||
|| slot != PCI_SLOT(pci_dev->devfn))
|
||||
|| slot != PCI_SLOT(pci_dev->devfn))
|
||||
continue;
|
||||
}
|
||||
if (thisboard->model == anypci_model) {
|
||||
@@ -250,11 +255,11 @@ pc236_find_pci(struct comedi_device *dev, int bus, int slot,
|
||||
/* No match found. */
|
||||
if (bus || slot) {
|
||||
printk(KERN_ERR
|
||||
"comedi%d: error! no %s found at pci %02x:%02x!\n",
|
||||
dev->minor, thisboard->name, bus, slot);
|
||||
"comedi%d: error! no %s found at pci %02x:%02x!\n",
|
||||
dev->minor, thisboard->name, bus, slot);
|
||||
} else {
|
||||
printk(KERN_ERR "comedi%d: error! no %s found!\n",
|
||||
dev->minor, thisboard->name);
|
||||
dev->minor, thisboard->name);
|
||||
}
|
||||
return -EIO;
|
||||
}
|
||||
@@ -279,7 +284,7 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
int ret;
|
||||
|
||||
printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor,
|
||||
PC236_DRIVER_NAME);
|
||||
PC236_DRIVER_NAME);
|
||||
/*
|
||||
* Allocate the private structure area. alloc_private() is a
|
||||
* convenient macro defined in comedidev.h.
|
||||
@@ -287,7 +292,7 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
ret = alloc_private(dev, sizeof(struct pc236_private));
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "comedi%d: error! out of memory!\n",
|
||||
dev->minor);
|
||||
dev->minor);
|
||||
return ret;
|
||||
}
|
||||
/* Process options. */
|
||||
@@ -311,8 +316,8 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
#endif /* CONFIG_COMEDI_PCI */
|
||||
default:
|
||||
printk(KERN_ERR
|
||||
"comedi%d: %s: BUG! cannot determine board type!\n",
|
||||
dev->minor, PC236_DRIVER_NAME);
|
||||
"comedi%d: %s: BUG! cannot determine board type!\n",
|
||||
dev->minor, PC236_DRIVER_NAME);
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
@@ -329,8 +334,8 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
ret = comedi_pci_enable(pci_dev, PC236_DRIVER_NAME);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR
|
||||
"comedi%d: error! cannot enable PCI device and request regions!\n",
|
||||
dev->minor);
|
||||
"comedi%d: error! cannot enable PCI device and request regions!\n",
|
||||
dev->minor);
|
||||
return ret;
|
||||
}
|
||||
devpriv->lcr_iobase = pci_resource_start(pci_dev, 1);
|
||||
@@ -353,7 +358,7 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
ret = alloc_subdevices(dev, 2);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "comedi%d: error! out of memory!\n",
|
||||
dev->minor);
|
||||
dev->minor);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -362,7 +367,7 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
ret = subdev_8255_init(dev, s, NULL, iobase);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "comedi%d: error! out of memory!\n",
|
||||
dev->minor);
|
||||
dev->minor);
|
||||
return ret;
|
||||
}
|
||||
s = dev->subdevices + 1;
|
||||
@@ -416,7 +421,7 @@ static int pc236_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
static int pc236_detach(struct comedi_device *dev)
|
||||
{
|
||||
printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
|
||||
PC236_DRIVER_NAME);
|
||||
PC236_DRIVER_NAME);
|
||||
if (devpriv) {
|
||||
pc236_intr_disable(dev);
|
||||
}
|
||||
@@ -442,7 +447,7 @@ static int pc236_detach(struct comedi_device *dev)
|
||||
}
|
||||
if (dev->board_name) {
|
||||
printk(KERN_INFO "comedi%d: %s removed\n",
|
||||
dev->minor, dev->board_name);
|
||||
dev->minor, dev->board_name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -452,11 +457,11 @@ static int pc236_detach(struct comedi_device *dev)
|
||||
* if there is a conflict.
|
||||
*/
|
||||
static int pc236_request_region(unsigned minor, unsigned long from,
|
||||
unsigned long extent)
|
||||
unsigned long extent)
|
||||
{
|
||||
if (!from || !request_region(from, extent, PC236_DRIVER_NAME)) {
|
||||
printk(KERN_ERR "comedi%d: I/O port conflict (%#lx,%lu)!\n",
|
||||
minor, from, extent);
|
||||
minor, from, extent);
|
||||
return -EIO;
|
||||
}
|
||||
return 0;
|
||||
@@ -516,13 +521,13 @@ static int pc236_intr_check(struct comedi_device *dev)
|
||||
#ifdef CONFIG_COMEDI_PCI
|
||||
if (devpriv->lcr_iobase) {
|
||||
if ((inl(devpriv->lcr_iobase + PLX9052_INTCSR)
|
||||
& PLX9052_INTCSR_LI1STAT_MASK)
|
||||
== PLX9052_INTCSR_LI1STAT_INACTIVE) {
|
||||
& PLX9052_INTCSR_LI1STAT_MASK)
|
||||
== PLX9052_INTCSR_LI1STAT_INACTIVE) {
|
||||
retval = 0;
|
||||
} else {
|
||||
/* Clear interrupt and keep it enabled. */
|
||||
outl(PCI236_INTR_ENABLE,
|
||||
devpriv->lcr_iobase + PLX9052_INTCSR);
|
||||
devpriv->lcr_iobase + PLX9052_INTCSR);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -536,8 +541,9 @@ static int pc236_intr_check(struct comedi_device *dev)
|
||||
* Input from subdevice 1.
|
||||
* Copied from the comedi_parport driver.
|
||||
*/
|
||||
static int pc236_intr_insn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int pc236_intr_insn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
data[1] = 0;
|
||||
return 2;
|
||||
@@ -547,8 +553,9 @@ static int pc236_intr_insn(struct comedi_device *dev, struct comedi_subdevice *s
|
||||
* Subdevice 1 command test.
|
||||
* Copied from the comedi_parport driver.
|
||||
*/
|
||||
static int pc236_intr_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd)
|
||||
static int pc236_intr_cmdtest(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd)
|
||||
{
|
||||
int err = 0;
|
||||
int tmp;
|
||||
@@ -635,7 +642,8 @@ static int pc236_intr_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
/*
|
||||
* Subdevice 1 cancel command.
|
||||
*/
|
||||
static int pc236_intr_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
static int pc236_intr_cancel(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
pc236_intr_disable(dev);
|
||||
|
||||
|
||||
@@ -74,36 +74,37 @@ struct pc263_board {
|
||||
};
|
||||
static const struct pc263_board pc263_boards[] = {
|
||||
{
|
||||
.name = "pc263",
|
||||
.fancy_name = "PC263",
|
||||
.bustype = isa_bustype,
|
||||
.model = pc263_model,
|
||||
},
|
||||
.name = "pc263",
|
||||
.fancy_name = "PC263",
|
||||
.bustype = isa_bustype,
|
||||
.model = pc263_model,
|
||||
},
|
||||
#ifdef CONFIG_COMEDI_PCI
|
||||
{
|
||||
.name = "pci263",
|
||||
.fancy_name = "PCI263",
|
||||
.devid = PCI_DEVICE_ID_AMPLICON_PCI263,
|
||||
.bustype = pci_bustype,
|
||||
.model = pci263_model,
|
||||
},
|
||||
.name = "pci263",
|
||||
.fancy_name = "PCI263",
|
||||
.devid = PCI_DEVICE_ID_AMPLICON_PCI263,
|
||||
.bustype = pci_bustype,
|
||||
.model = pci263_model,
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_COMEDI_PCI
|
||||
{
|
||||
.name = PC263_DRIVER_NAME,
|
||||
.fancy_name = PC263_DRIVER_NAME,
|
||||
.devid = PCI_DEVICE_ID_INVALID,
|
||||
.bustype = pci_bustype,
|
||||
.model = anypci_model, /* wildcard */
|
||||
},
|
||||
.name = PC263_DRIVER_NAME,
|
||||
.fancy_name = PC263_DRIVER_NAME,
|
||||
.devid = PCI_DEVICE_ID_INVALID,
|
||||
.bustype = pci_bustype,
|
||||
.model = anypci_model, /* wildcard */
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef CONFIG_COMEDI_PCI
|
||||
static DEFINE_PCI_DEVICE_TABLE(pc263_pci_table) = {
|
||||
{PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI263, PCI_ANY_ID,
|
||||
PCI_ANY_ID, 0, 0, 0},
|
||||
{0}
|
||||
{
|
||||
PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI263,
|
||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
0}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, pc263_pci_table);
|
||||
@@ -145,11 +146,13 @@ static struct comedi_driver driver_amplc_pc263 = {
|
||||
};
|
||||
|
||||
static int pc263_request_region(unsigned minor, unsigned long from,
|
||||
unsigned long extent);
|
||||
static int pc263_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int pc263_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
unsigned long extent);
|
||||
static int pc263_dio_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int pc263_dio_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
/*
|
||||
* This function looks for a PCI device matching the requested board name,
|
||||
@@ -158,7 +161,7 @@ static int pc263_dio_insn_config(struct comedi_device *dev, struct comedi_subdev
|
||||
#ifdef CONFIG_COMEDI_PCI
|
||||
static int
|
||||
pc263_find_pci(struct comedi_device *dev, int bus, int slot,
|
||||
struct pci_dev **pci_dev_p)
|
||||
struct pci_dev **pci_dev_p)
|
||||
{
|
||||
struct pci_dev *pci_dev = NULL;
|
||||
|
||||
@@ -166,13 +169,13 @@ pc263_find_pci(struct comedi_device *dev, int bus, int slot,
|
||||
|
||||
/* Look for matching PCI device. */
|
||||
for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL);
|
||||
pci_dev != NULL;
|
||||
pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON,
|
||||
PCI_ANY_ID, pci_dev)) {
|
||||
pci_dev != NULL;
|
||||
pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON,
|
||||
PCI_ANY_ID, pci_dev)) {
|
||||
/* If bus/slot specified, check them. */
|
||||
if (bus || slot) {
|
||||
if (bus != pci_dev->bus->number
|
||||
|| slot != PCI_SLOT(pci_dev->devfn))
|
||||
|| slot != PCI_SLOT(pci_dev->devfn))
|
||||
continue;
|
||||
}
|
||||
if (thisboard->model == anypci_model) {
|
||||
@@ -203,11 +206,11 @@ pc263_find_pci(struct comedi_device *dev, int bus, int slot,
|
||||
/* No match found. */
|
||||
if (bus || slot) {
|
||||
printk(KERN_ERR
|
||||
"comedi%d: error! no %s found at pci %02x:%02x!\n",
|
||||
dev->minor, thisboard->name, bus, slot);
|
||||
"comedi%d: error! no %s found at pci %02x:%02x!\n",
|
||||
dev->minor, thisboard->name, bus, slot);
|
||||
} else {
|
||||
printk(KERN_ERR "comedi%d: error! no %s found!\n",
|
||||
dev->minor, thisboard->name);
|
||||
dev->minor, thisboard->name);
|
||||
}
|
||||
return -EIO;
|
||||
}
|
||||
@@ -230,7 +233,7 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
int ret;
|
||||
|
||||
printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor,
|
||||
PC263_DRIVER_NAME);
|
||||
PC263_DRIVER_NAME);
|
||||
/*
|
||||
* Allocate the private structure area. alloc_private() is a
|
||||
* convenient macro defined in comedidev.h.
|
||||
@@ -239,7 +242,7 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
ret = alloc_private(dev, sizeof(struct pc263_private));
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "comedi%d: error! out of memory!\n",
|
||||
dev->minor);
|
||||
dev->minor);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
@@ -261,8 +264,8 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
#endif /* CONFIG_COMEDI_PCI */
|
||||
default:
|
||||
printk(KERN_ERR
|
||||
"comedi%d: %s: BUG! cannot determine board type!\n",
|
||||
dev->minor, PC263_DRIVER_NAME);
|
||||
"comedi%d: %s: BUG! cannot determine board type!\n",
|
||||
dev->minor, PC263_DRIVER_NAME);
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
@@ -278,8 +281,8 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
ret = comedi_pci_enable(pci_dev, PC263_DRIVER_NAME);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR
|
||||
"comedi%d: error! cannot enable PCI device and request regions!\n",
|
||||
dev->minor);
|
||||
"comedi%d: error! cannot enable PCI device and request regions!\n",
|
||||
dev->minor);
|
||||
return ret;
|
||||
}
|
||||
iobase = pci_resource_start(pci_dev, 2);
|
||||
@@ -300,7 +303,7 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
ret = alloc_subdevices(dev, 1);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "comedi%d: error! out of memory!\n",
|
||||
dev->minor);
|
||||
dev->minor);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -344,7 +347,7 @@ static int pc263_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
static int pc263_detach(struct comedi_device *dev)
|
||||
{
|
||||
printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
|
||||
PC263_DRIVER_NAME);
|
||||
PC263_DRIVER_NAME);
|
||||
|
||||
#ifdef CONFIG_COMEDI_PCI
|
||||
if (devpriv)
|
||||
@@ -366,7 +369,7 @@ static int pc263_detach(struct comedi_device *dev)
|
||||
}
|
||||
if (dev->board_name) {
|
||||
printk(KERN_INFO "comedi%d: %s removed\n",
|
||||
dev->minor, dev->board_name);
|
||||
dev->minor, dev->board_name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -376,11 +379,11 @@ static int pc263_detach(struct comedi_device *dev)
|
||||
* if there is a conflict.
|
||||
*/
|
||||
static int pc263_request_region(unsigned minor, unsigned long from,
|
||||
unsigned long extent)
|
||||
unsigned long extent)
|
||||
{
|
||||
if (!from || !request_region(from, extent, PC263_DRIVER_NAME)) {
|
||||
printk(KERN_ERR "comedi%d: I/O port conflict (%#lx,%lu)!\n",
|
||||
minor, from, extent);
|
||||
minor, from, extent);
|
||||
return -EIO;
|
||||
}
|
||||
return 0;
|
||||
@@ -391,8 +394,9 @@ static int pc263_request_region(unsigned minor, unsigned long from,
|
||||
* useful to applications if you implement the insn_bits interface.
|
||||
* This allows packed reading/writing of the DIO channels. The
|
||||
* comedi core can convert between insn_bits and insn_read/write */
|
||||
static int pc263_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int pc263_dio_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
if (insn->n != 2)
|
||||
return -EINVAL;
|
||||
@@ -416,8 +420,9 @@ static int pc263_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevic
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int pc263_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int pc263_dio_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
if (insn->n != 1)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -283,15 +283,15 @@ Passing a zero for an option is the same as leaving it unspecified.
|
||||
static const struct comedi_lrange range_pci224_internal = {
|
||||
8,
|
||||
{
|
||||
BIP_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(2.5),
|
||||
BIP_RANGE(1.25),
|
||||
UNI_RANGE(10),
|
||||
UNI_RANGE(5),
|
||||
UNI_RANGE(2.5),
|
||||
UNI_RANGE(1.25),
|
||||
}
|
||||
BIP_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(2.5),
|
||||
BIP_RANGE(1.25),
|
||||
UNI_RANGE(10),
|
||||
UNI_RANGE(5),
|
||||
UNI_RANGE(2.5),
|
||||
UNI_RANGE(1.25),
|
||||
}
|
||||
};
|
||||
|
||||
static const unsigned short hwrange_pci224_internal[8] = {
|
||||
@@ -309,9 +309,9 @@ static const unsigned short hwrange_pci224_internal[8] = {
|
||||
static const struct comedi_lrange range_pci224_external = {
|
||||
2,
|
||||
{
|
||||
RANGE_ext(-1, 1), /* bipolar [-Vref,+Vref] */
|
||||
RANGE_ext(0, 1), /* unipolar [0,+Vref] */
|
||||
}
|
||||
RANGE_ext(-1, 1), /* bipolar [-Vref,+Vref] */
|
||||
RANGE_ext(0, 1), /* unipolar [0,+Vref] */
|
||||
}
|
||||
};
|
||||
|
||||
static const unsigned short hwrange_pci224_external[2] = {
|
||||
@@ -324,8 +324,8 @@ static const unsigned short hwrange_pci224_external[2] = {
|
||||
static const struct comedi_lrange range_pci234_ext2 = {
|
||||
1,
|
||||
{
|
||||
RANGE_ext(-2, 2),
|
||||
}
|
||||
RANGE_ext(-2, 2),
|
||||
}
|
||||
};
|
||||
|
||||
/* The hardware selectable Vref external range for PCI234
|
||||
@@ -333,8 +333,8 @@ static const struct comedi_lrange range_pci234_ext2 = {
|
||||
static const struct comedi_lrange range_pci234_ext = {
|
||||
1,
|
||||
{
|
||||
RANGE_ext(-1, 1),
|
||||
}
|
||||
RANGE_ext(-1, 1),
|
||||
}
|
||||
};
|
||||
|
||||
/* This serves for all the PCI234 ranges. */
|
||||
@@ -358,24 +358,24 @@ struct pci224_board {
|
||||
|
||||
static const struct pci224_board pci224_boards[] = {
|
||||
{
|
||||
.name = "pci224",
|
||||
.devid = PCI_DEVICE_ID_AMPLICON_PCI224,
|
||||
.model = pci224_model,
|
||||
.ao_chans = 16,
|
||||
.ao_bits = 12,
|
||||
},
|
||||
.name = "pci224",
|
||||
.devid = PCI_DEVICE_ID_AMPLICON_PCI224,
|
||||
.model = pci224_model,
|
||||
.ao_chans = 16,
|
||||
.ao_bits = 12,
|
||||
},
|
||||
{
|
||||
.name = "pci234",
|
||||
.devid = PCI_DEVICE_ID_AMPLICON_PCI234,
|
||||
.model = pci234_model,
|
||||
.ao_chans = 4,
|
||||
.ao_bits = 16,
|
||||
},
|
||||
.name = "pci234",
|
||||
.devid = PCI_DEVICE_ID_AMPLICON_PCI234,
|
||||
.model = pci234_model,
|
||||
.ao_chans = 4,
|
||||
.ao_bits = 16,
|
||||
},
|
||||
{
|
||||
.name = DRIVER_NAME,
|
||||
.devid = PCI_DEVICE_ID_INVALID,
|
||||
.model = any_model, /* wildcard */
|
||||
},
|
||||
.name = DRIVER_NAME,
|
||||
.devid = PCI_DEVICE_ID_INVALID,
|
||||
.model = any_model, /* wildcard */
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -383,11 +383,12 @@ static const struct pci224_board pci224_boards[] = {
|
||||
*/
|
||||
|
||||
static DEFINE_PCI_DEVICE_TABLE(pci224_pci_table) = {
|
||||
{PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI224,
|
||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI234,
|
||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{0}
|
||||
{
|
||||
PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI224,
|
||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI234,
|
||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
0}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, pci224_pci_table);
|
||||
@@ -428,7 +429,8 @@ struct pci224_private {
|
||||
* the board, and also about the kernel module that contains
|
||||
* the device code.
|
||||
*/
|
||||
static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int pci224_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int pci224_detach(struct comedi_device *dev);
|
||||
static struct comedi_driver driver_amplc_pci224 = {
|
||||
.driver_name = DRIVER_NAME,
|
||||
@@ -446,7 +448,8 @@ COMEDI_PCI_INITCLEANUP(driver_amplc_pci224, pci224_pci_table);
|
||||
* Called from the 'insn_write' function to perform a single write.
|
||||
*/
|
||||
static void
|
||||
pci224_ao_set_data(struct comedi_device *dev, int chan, int range, unsigned int data)
|
||||
pci224_ao_set_data(struct comedi_device *dev, int chan, int range,
|
||||
unsigned int data)
|
||||
{
|
||||
unsigned short mangled;
|
||||
|
||||
@@ -456,9 +459,10 @@ pci224_ao_set_data(struct comedi_device *dev, int chan, int range, unsigned int
|
||||
outw(1 << chan, dev->iobase + PCI224_DACCEN);
|
||||
/* Set range and reset FIFO. */
|
||||
devpriv->daccon = COMBINE(devpriv->daccon, devpriv->hwrange[range],
|
||||
(PCI224_DACCON_POLAR_MASK | PCI224_DACCON_VREF_MASK));
|
||||
(PCI224_DACCON_POLAR_MASK |
|
||||
PCI224_DACCON_VREF_MASK));
|
||||
outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
|
||||
dev->iobase + PCI224_DACCON);
|
||||
dev->iobase + PCI224_DACCON);
|
||||
/*
|
||||
* Mangle the data. The hardware expects:
|
||||
* - bipolar: 16-bit 2's complement
|
||||
@@ -466,7 +470,7 @@ pci224_ao_set_data(struct comedi_device *dev, int chan, int range, unsigned int
|
||||
*/
|
||||
mangled = (unsigned short)data << (16 - thisboard->ao_bits);
|
||||
if ((devpriv->daccon & PCI224_DACCON_POLAR_MASK) ==
|
||||
PCI224_DACCON_POLAR_BI) {
|
||||
PCI224_DACCON_POLAR_BI) {
|
||||
mangled ^= 0x8000;
|
||||
}
|
||||
/* Write mangled data to the FIFO. */
|
||||
@@ -480,7 +484,7 @@ pci224_ao_set_data(struct comedi_device *dev, int chan, int range, unsigned int
|
||||
*/
|
||||
static int
|
||||
pci224_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int i;
|
||||
int chan, range;
|
||||
@@ -507,7 +511,7 @@ pci224_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
*/
|
||||
static int
|
||||
pci224_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int i;
|
||||
int chan;
|
||||
@@ -526,7 +530,7 @@ pci224_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
*/
|
||||
static void
|
||||
pci224_cascade_ns_to_timer(int osc_base, unsigned int *d1, unsigned int *d2,
|
||||
unsigned int *nanosec, int round_mode)
|
||||
unsigned int *nanosec, int round_mode)
|
||||
{
|
||||
i8253_cascade_ns_to_timer(osc_base, d1, d2, nanosec, round_mode);
|
||||
}
|
||||
@@ -534,7 +538,8 @@ pci224_cascade_ns_to_timer(int osc_base, unsigned int *d1, unsigned int *d2,
|
||||
/*
|
||||
* Kills a command running on the AO subdevice.
|
||||
*/
|
||||
static void pci224_ao_stop(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
static void pci224_ao_stop(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
@@ -565,16 +570,19 @@ static void pci224_ao_stop(struct comedi_device *dev, struct comedi_subdevice *s
|
||||
/* Reconfigure DAC for insn_write usage. */
|
||||
outw(0, dev->iobase + PCI224_DACCEN); /* Disable channels. */
|
||||
devpriv->daccon = COMBINE(devpriv->daccon,
|
||||
PCI224_DACCON_TRIG_SW | PCI224_DACCON_FIFOINTR_EMPTY,
|
||||
PCI224_DACCON_TRIG_MASK | PCI224_DACCON_FIFOINTR_MASK);
|
||||
PCI224_DACCON_TRIG_SW |
|
||||
PCI224_DACCON_FIFOINTR_EMPTY,
|
||||
PCI224_DACCON_TRIG_MASK |
|
||||
PCI224_DACCON_FIFOINTR_MASK);
|
||||
outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
|
||||
dev->iobase + PCI224_DACCON);
|
||||
dev->iobase + PCI224_DACCON);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handles start of acquisition for the AO subdevice.
|
||||
*/
|
||||
static void pci224_ao_start(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
static void pci224_ao_start(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
struct comedi_cmd *cmd = &s->async->cmd;
|
||||
unsigned long flags;
|
||||
@@ -601,7 +609,8 @@ static void pci224_ao_start(struct comedi_device *dev, struct comedi_subdevice *
|
||||
/*
|
||||
* Handles interrupts from the DAC FIFO.
|
||||
*/
|
||||
static void pci224_ao_handle_fifo(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
static void pci224_ao_handle_fifo(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
struct comedi_cmd *cmd = &s->async->cmd;
|
||||
unsigned int num_scans;
|
||||
@@ -630,8 +639,7 @@ static void pci224_ao_handle_fifo(struct comedi_device *dev, struct comedi_subde
|
||||
switch (dacstat & PCI224_DACCON_FIFOFL_MASK) {
|
||||
case PCI224_DACCON_FIFOFL_EMPTY:
|
||||
room = PCI224_FIFO_ROOM_EMPTY;
|
||||
if (!devpriv->ao_stop_continuous
|
||||
&& devpriv->ao_stop_count == 0) {
|
||||
if (!devpriv->ao_stop_continuous && devpriv->ao_stop_count == 0) {
|
||||
/* FIFO empty at end of counted acquisition. */
|
||||
pci224_ao_stop(dev, s);
|
||||
s->async->events |= COMEDI_CB_EOA;
|
||||
@@ -656,7 +664,7 @@ static void pci224_ao_handle_fifo(struct comedi_device *dev, struct comedi_subde
|
||||
pci224_ao_stop(dev, s);
|
||||
s->async->events |= COMEDI_CB_OVERFLOW;
|
||||
printk(KERN_ERR "comedi%d: "
|
||||
"AO buffer underrun\n", dev->minor);
|
||||
"AO buffer underrun\n", dev->minor);
|
||||
}
|
||||
}
|
||||
/* Determine how many new scans can be put in the FIFO. */
|
||||
@@ -670,11 +678,10 @@ static void pci224_ao_handle_fifo(struct comedi_device *dev, struct comedi_subde
|
||||
/* Process scans. */
|
||||
for (n = 0; n < num_scans; n++) {
|
||||
cfc_read_array_from_buffer(s, &devpriv->ao_scan_vals[0],
|
||||
bytes_per_scan);
|
||||
bytes_per_scan);
|
||||
for (i = 0; i < cmd->chanlist_len; i++) {
|
||||
outw(devpriv->ao_scan_vals[devpriv->
|
||||
ao_scan_order[i]],
|
||||
dev->iobase + PCI224_DACDATA);
|
||||
outw(devpriv->ao_scan_vals[devpriv->ao_scan_order[i]],
|
||||
dev->iobase + PCI224_DACDATA);
|
||||
}
|
||||
}
|
||||
if (!devpriv->ao_stop_continuous) {
|
||||
@@ -685,14 +692,13 @@ static void pci224_ao_handle_fifo(struct comedi_device *dev, struct comedi_subde
|
||||
* until FIFO is empty.
|
||||
*/
|
||||
devpriv->daccon = COMBINE(devpriv->daccon,
|
||||
PCI224_DACCON_FIFOINTR_EMPTY,
|
||||
PCI224_DACCON_FIFOINTR_MASK);
|
||||
outw(devpriv->daccon,
|
||||
dev->iobase + PCI224_DACCON);
|
||||
PCI224_DACCON_FIFOINTR_EMPTY,
|
||||
PCI224_DACCON_FIFOINTR_MASK);
|
||||
outw(devpriv->daccon, dev->iobase + PCI224_DACCON);
|
||||
}
|
||||
}
|
||||
if ((devpriv->daccon & PCI224_DACCON_TRIG_MASK) ==
|
||||
PCI224_DACCON_TRIG_NONE) {
|
||||
PCI224_DACCON_TRIG_NONE) {
|
||||
unsigned short trig;
|
||||
|
||||
/*
|
||||
@@ -718,7 +724,7 @@ static void pci224_ao_handle_fifo(struct comedi_device *dev, struct comedi_subde
|
||||
}
|
||||
}
|
||||
devpriv->daccon = COMBINE(devpriv->daccon, trig,
|
||||
PCI224_DACCON_TRIG_MASK);
|
||||
PCI224_DACCON_TRIG_MASK);
|
||||
outw(devpriv->daccon, dev->iobase + PCI224_DACCON);
|
||||
}
|
||||
if (s->async->events) {
|
||||
@@ -731,7 +737,7 @@ static void pci224_ao_handle_fifo(struct comedi_device *dev, struct comedi_subde
|
||||
*/
|
||||
static int
|
||||
pci224_ao_inttrig_start(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
unsigned int trignum)
|
||||
unsigned int trignum)
|
||||
{
|
||||
if (trignum != 0)
|
||||
return -EINVAL;
|
||||
@@ -750,7 +756,8 @@ pci224_ao_inttrig_start(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
* 'do_cmdtest' function for AO subdevice.
|
||||
*/
|
||||
static int
|
||||
pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd)
|
||||
pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd)
|
||||
{
|
||||
int err = 0;
|
||||
unsigned int tmp;
|
||||
@@ -828,13 +835,13 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct
|
||||
/* Force to external trigger 0. */
|
||||
if ((cmd->start_arg & ~CR_FLAGS_MASK) != 0) {
|
||||
cmd->start_arg = COMBINE(cmd->start_arg, 0,
|
||||
~CR_FLAGS_MASK);
|
||||
~CR_FLAGS_MASK);
|
||||
err++;
|
||||
}
|
||||
/* The only flag allowed is CR_EDGE, which is ignored. */
|
||||
if ((cmd->start_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
|
||||
cmd->start_arg = COMBINE(cmd->start_arg, 0,
|
||||
CR_FLAGS_MASK & ~CR_EDGE);
|
||||
CR_FLAGS_MASK & ~CR_EDGE);
|
||||
err++;
|
||||
}
|
||||
break;
|
||||
@@ -859,14 +866,16 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct
|
||||
/* Force to external trigger 0. */
|
||||
if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) {
|
||||
cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
|
||||
~CR_FLAGS_MASK);
|
||||
~CR_FLAGS_MASK);
|
||||
err++;
|
||||
}
|
||||
/* Only allow flags CR_EDGE and CR_INVERT. Ignore CR_EDGE. */
|
||||
if ((cmd->scan_begin_arg & CR_FLAGS_MASK &
|
||||
~(CR_EDGE | CR_INVERT)) != 0) {
|
||||
~(CR_EDGE | CR_INVERT)) != 0) {
|
||||
cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
|
||||
CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT));
|
||||
CR_FLAGS_MASK & ~(CR_EDGE
|
||||
|
|
||||
CR_INVERT));
|
||||
err++;
|
||||
}
|
||||
break;
|
||||
@@ -892,13 +901,13 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct
|
||||
/* Force to external trigger 0. */
|
||||
if ((cmd->stop_arg & ~CR_FLAGS_MASK) != 0) {
|
||||
cmd->stop_arg = COMBINE(cmd->stop_arg, 0,
|
||||
~CR_FLAGS_MASK);
|
||||
~CR_FLAGS_MASK);
|
||||
err++;
|
||||
}
|
||||
/* The only flag allowed is CR_EDGE, which is ignored. */
|
||||
if ((cmd->stop_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
|
||||
cmd->stop_arg = COMBINE(cmd->stop_arg, 0,
|
||||
CR_FLAGS_MASK & ~CR_EDGE);
|
||||
CR_FLAGS_MASK & ~CR_EDGE);
|
||||
}
|
||||
break;
|
||||
case TRIG_NONE:
|
||||
@@ -935,14 +944,14 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct
|
||||
/* Be careful to avoid overflow! */
|
||||
div2 = cmd->scan_begin_arg / TIMEBASE_10MHZ;
|
||||
div2 += (round + cmd->scan_begin_arg % TIMEBASE_10MHZ) /
|
||||
TIMEBASE_10MHZ;
|
||||
TIMEBASE_10MHZ;
|
||||
if (div2 <= 0x10000) {
|
||||
/* A single timer will suffice. */
|
||||
if (div2 < 2)
|
||||
div2 = 2;
|
||||
cmd->scan_begin_arg = div2 * TIMEBASE_10MHZ;
|
||||
if (cmd->scan_begin_arg < div2 ||
|
||||
cmd->scan_begin_arg < TIMEBASE_10MHZ) {
|
||||
cmd->scan_begin_arg < TIMEBASE_10MHZ) {
|
||||
/* Overflow! */
|
||||
cmd->scan_begin_arg = MAX_SCAN_PERIOD;
|
||||
}
|
||||
@@ -951,7 +960,8 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct
|
||||
div1 = devpriv->cached_div1;
|
||||
div2 = devpriv->cached_div2;
|
||||
pci224_cascade_ns_to_timer(TIMEBASE_10MHZ, &div1, &div2,
|
||||
&cmd->scan_begin_arg, round_mode);
|
||||
&cmd->scan_begin_arg,
|
||||
round_mode);
|
||||
devpriv->cached_div1 = div1;
|
||||
devpriv->cached_div2 = div2;
|
||||
}
|
||||
@@ -1061,12 +1071,15 @@ static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
* N.B. DAC FIFO interrupts are currently disabled.
|
||||
*/
|
||||
devpriv->daccon = COMBINE(devpriv->daccon,
|
||||
(devpriv->hwrange[range] | PCI224_DACCON_TRIG_NONE |
|
||||
PCI224_DACCON_FIFOINTR_NHALF),
|
||||
(PCI224_DACCON_POLAR_MASK | PCI224_DACCON_VREF_MASK |
|
||||
PCI224_DACCON_TRIG_MASK | PCI224_DACCON_FIFOINTR_MASK));
|
||||
(devpriv->
|
||||
hwrange[range] | PCI224_DACCON_TRIG_NONE |
|
||||
PCI224_DACCON_FIFOINTR_NHALF),
|
||||
(PCI224_DACCON_POLAR_MASK |
|
||||
PCI224_DACCON_VREF_MASK |
|
||||
PCI224_DACCON_TRIG_MASK |
|
||||
PCI224_DACCON_FIFOINTR_MASK));
|
||||
outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
|
||||
dev->iobase + PCI224_DACCON);
|
||||
dev->iobase + PCI224_DACCON);
|
||||
|
||||
if (cmd->scan_begin_src == TRIG_TIMER) {
|
||||
unsigned int div1, div2, round;
|
||||
@@ -1089,7 +1102,7 @@ static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
/* Be careful to avoid overflow! */
|
||||
div2 = cmd->scan_begin_arg / TIMEBASE_10MHZ;
|
||||
div2 += (round + cmd->scan_begin_arg % TIMEBASE_10MHZ) /
|
||||
TIMEBASE_10MHZ;
|
||||
TIMEBASE_10MHZ;
|
||||
if (div2 <= 0x10000) {
|
||||
/* A single timer will suffice. */
|
||||
if (div2 < 2)
|
||||
@@ -1101,7 +1114,7 @@ static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
div1 = devpriv->cached_div1;
|
||||
div2 = devpriv->cached_div2;
|
||||
pci224_cascade_ns_to_timer(TIMEBASE_10MHZ, &div1, &div2,
|
||||
&ns, round_mode);
|
||||
&ns, round_mode);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1110,25 +1123,25 @@ static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
*/
|
||||
/* Make sure Z2-0 is gated on. */
|
||||
outb(GAT_CONFIG(0, GAT_VCC),
|
||||
devpriv->iobase1 + PCI224_ZGAT_SCE);
|
||||
devpriv->iobase1 + PCI224_ZGAT_SCE);
|
||||
if (div1 == 1) {
|
||||
/* Not cascading. Z2-0 needs 10 MHz clock. */
|
||||
outb(CLK_CONFIG(0, CLK_10MHZ),
|
||||
devpriv->iobase1 + PCI224_ZCLK_SCE);
|
||||
devpriv->iobase1 + PCI224_ZCLK_SCE);
|
||||
} else {
|
||||
/* Cascading with Z2-2. */
|
||||
/* Make sure Z2-2 is gated on. */
|
||||
outb(GAT_CONFIG(2, GAT_VCC),
|
||||
devpriv->iobase1 + PCI224_ZGAT_SCE);
|
||||
devpriv->iobase1 + PCI224_ZGAT_SCE);
|
||||
/* Z2-2 needs 10 MHz clock. */
|
||||
outb(CLK_CONFIG(2, CLK_10MHZ),
|
||||
devpriv->iobase1 + PCI224_ZCLK_SCE);
|
||||
devpriv->iobase1 + PCI224_ZCLK_SCE);
|
||||
/* Load Z2-2 mode (2) and counter (div1). */
|
||||
i8254_load(devpriv->iobase1 + PCI224_Z2_CT0, 0,
|
||||
2, div1, 2);
|
||||
2, div1, 2);
|
||||
/* Z2-0 is clocked from Z2-2's output. */
|
||||
outb(CLK_CONFIG(0, CLK_OUTNM1),
|
||||
devpriv->iobase1 + PCI224_ZCLK_SCE);
|
||||
devpriv->iobase1 + PCI224_ZCLK_SCE);
|
||||
}
|
||||
/* Load Z2-0 mode (2) and counter (div2). */
|
||||
i8254_load(devpriv->iobase1 + PCI224_Z2_CT0, 0, 0, div2, 2);
|
||||
@@ -1174,7 +1187,8 @@ static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
/*
|
||||
* 'cancel' function for AO subdevice.
|
||||
*/
|
||||
static int pci224_ao_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
static int pci224_ao_cancel(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
pci224_ao_stop(dev, s);
|
||||
return 0;
|
||||
@@ -1184,8 +1198,8 @@ static int pci224_ao_cancel(struct comedi_device *dev, struct comedi_subdevice *
|
||||
* 'munge' data for AO command.
|
||||
*/
|
||||
static void
|
||||
pci224_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s, void *data,
|
||||
unsigned int num_bytes, unsigned int chan_index)
|
||||
pci224_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
void *data, unsigned int num_bytes, unsigned int chan_index)
|
||||
{
|
||||
struct comedi_async *async = s->async;
|
||||
short *array = data;
|
||||
@@ -1198,7 +1212,7 @@ pci224_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s, void *dat
|
||||
shift = 16 - thisboard->ao_bits;
|
||||
/* Channels will be all bipolar or all unipolar. */
|
||||
if ((devpriv->hwrange[CR_RANGE(async->cmd.chanlist[0])] &
|
||||
PCI224_DACCON_POLAR_MASK) == PCI224_DACCON_POLAR_UNI) {
|
||||
PCI224_DACCON_POLAR_MASK) == PCI224_DACCON_POLAR_UNI) {
|
||||
/* Unipolar */
|
||||
offset = 0;
|
||||
} else {
|
||||
@@ -1253,7 +1267,7 @@ static irqreturn_t pci224_interrupt(int irq, void *d)
|
||||
spin_lock_irqsave(&devpriv->ao_spinlock, flags);
|
||||
if (curenab != devpriv->intsce) {
|
||||
outb(devpriv->intsce,
|
||||
devpriv->iobase1 + PCI224_INT_SCE);
|
||||
devpriv->iobase1 + PCI224_INT_SCE);
|
||||
}
|
||||
devpriv->intr_running = 0;
|
||||
spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
|
||||
@@ -1267,7 +1281,7 @@ static irqreturn_t pci224_interrupt(int irq, void *d)
|
||||
*/
|
||||
static int
|
||||
pci224_find_pci(struct comedi_device *dev, int bus, int slot,
|
||||
struct pci_dev **pci_dev_p)
|
||||
struct pci_dev **pci_dev_p)
|
||||
{
|
||||
struct pci_dev *pci_dev = NULL;
|
||||
|
||||
@@ -1275,13 +1289,13 @@ pci224_find_pci(struct comedi_device *dev, int bus, int slot,
|
||||
|
||||
/* Look for matching PCI device. */
|
||||
for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL);
|
||||
pci_dev != NULL;
|
||||
pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID,
|
||||
pci_dev)) {
|
||||
pci_dev != NULL;
|
||||
pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID,
|
||||
pci_dev)) {
|
||||
/* If bus/slot specified, check them. */
|
||||
if (bus || slot) {
|
||||
if (bus != pci_dev->bus->number
|
||||
|| slot != PCI_SLOT(pci_dev->devfn))
|
||||
|| slot != PCI_SLOT(pci_dev->devfn))
|
||||
continue;
|
||||
}
|
||||
if (thisboard->model == any_model) {
|
||||
@@ -1310,11 +1324,11 @@ pci224_find_pci(struct comedi_device *dev, int bus, int slot,
|
||||
/* No match found. */
|
||||
if (bus || slot) {
|
||||
printk(KERN_ERR "comedi%d: error! "
|
||||
"no %s found at pci %02x:%02x!\n",
|
||||
dev->minor, thisboard->name, bus, slot);
|
||||
"no %s found at pci %02x:%02x!\n",
|
||||
dev->minor, thisboard->name, bus, slot);
|
||||
} else {
|
||||
printk(KERN_ERR "comedi%d: error! no %s found!\n",
|
||||
dev->minor, thisboard->name);
|
||||
dev->minor, thisboard->name);
|
||||
}
|
||||
return -EIO;
|
||||
}
|
||||
@@ -1341,7 +1355,7 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
ret = alloc_private(dev, sizeof(struct pci224_private));
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "comedi%d: error! out of memory!\n",
|
||||
dev->minor);
|
||||
dev->minor);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1353,8 +1367,8 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
ret = comedi_pci_enable(pci_dev, DRIVER_NAME);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR
|
||||
"comedi%d: error! cannot enable PCI device "
|
||||
"and request regions!\n", dev->minor);
|
||||
"comedi%d: error! cannot enable PCI device "
|
||||
"and request regions!\n", dev->minor);
|
||||
return ret;
|
||||
}
|
||||
spin_lock_init(&devpriv->ao_spinlock);
|
||||
@@ -1365,21 +1379,21 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
|
||||
/* Allocate readback buffer for AO channels. */
|
||||
devpriv->ao_readback = kmalloc(sizeof(devpriv->ao_readback[0]) *
|
||||
thisboard->ao_chans, GFP_KERNEL);
|
||||
thisboard->ao_chans, GFP_KERNEL);
|
||||
if (!devpriv->ao_readback) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Allocate buffer to hold values for AO channel scan. */
|
||||
devpriv->ao_scan_vals = kmalloc(sizeof(devpriv->ao_scan_vals[0]) *
|
||||
thisboard->ao_chans, GFP_KERNEL);
|
||||
thisboard->ao_chans, GFP_KERNEL);
|
||||
if (!devpriv->ao_scan_vals) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Allocate buffer to hold AO channel scan order. */
|
||||
devpriv->ao_scan_order = kmalloc(sizeof(devpriv->ao_scan_order[0]) *
|
||||
thisboard->ao_chans, GFP_KERNEL);
|
||||
thisboard->ao_chans, GFP_KERNEL);
|
||||
if (!devpriv->ao_scan_order) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
@@ -1393,15 +1407,16 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
outw(0, dev->iobase + PCI224_DACCEN);
|
||||
outw(0, dev->iobase + PCI224_FIFOSIZ);
|
||||
devpriv->daccon = (PCI224_DACCON_TRIG_SW | PCI224_DACCON_POLAR_BI |
|
||||
PCI224_DACCON_FIFOENAB | PCI224_DACCON_FIFOINTR_EMPTY);
|
||||
PCI224_DACCON_FIFOENAB |
|
||||
PCI224_DACCON_FIFOINTR_EMPTY);
|
||||
outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
|
||||
dev->iobase + PCI224_DACCON);
|
||||
dev->iobase + PCI224_DACCON);
|
||||
|
||||
/* Allocate subdevices. There is only one! */
|
||||
ret = alloc_subdevices(dev, 1);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "comedi%d: error! out of memory!\n",
|
||||
dev->minor);
|
||||
dev->minor);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1427,22 +1442,22 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
const struct comedi_lrange **range_table_list;
|
||||
|
||||
s->range_table_list = range_table_list =
|
||||
kmalloc(sizeof(struct comedi_lrange *) * s->n_chan,
|
||||
GFP_KERNEL);
|
||||
kmalloc(sizeof(struct comedi_lrange *) * s->n_chan,
|
||||
GFP_KERNEL);
|
||||
if (!s->range_table_list) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
for (n = 2; n < 3 + s->n_chan; n++) {
|
||||
if (it->options[n] < 0 || it->options[n] > 1) {
|
||||
printk(KERN_WARNING "comedi%d: %s: warning! "
|
||||
"bad options[%u]=%d\n",
|
||||
dev->minor, DRIVER_NAME, n,
|
||||
it->options[n]);
|
||||
"bad options[%u]=%d\n",
|
||||
dev->minor, DRIVER_NAME, n,
|
||||
it->options[n]);
|
||||
}
|
||||
}
|
||||
for (n = 0; n < s->n_chan; n++) {
|
||||
if (n < COMEDI_NDEVCONFOPTS - 3 &&
|
||||
it->options[3 + n] == 1) {
|
||||
it->options[3 + n] == 1) {
|
||||
if (it->options[2] == 1) {
|
||||
range_table_list[n] = &range_pci234_ext;
|
||||
} else {
|
||||
@@ -1451,7 +1466,7 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
} else {
|
||||
if (it->options[2] == 1) {
|
||||
range_table_list[n] =
|
||||
&range_pci234_ext2;
|
||||
&range_pci234_ext2;
|
||||
} else {
|
||||
range_table_list[n] = &range_bipolar10;
|
||||
}
|
||||
@@ -1466,9 +1481,8 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
} else {
|
||||
if (it->options[2] != 0) {
|
||||
printk(KERN_WARNING "comedi%d: %s: warning! "
|
||||
"bad options[2]=%d\n",
|
||||
dev->minor, DRIVER_NAME,
|
||||
it->options[2]);
|
||||
"bad options[2]=%d\n",
|
||||
dev->minor, DRIVER_NAME, it->options[2]);
|
||||
}
|
||||
s->range_table = &range_pci224_internal;
|
||||
devpriv->hwrange = hwrange_pci224_internal;
|
||||
@@ -1482,7 +1496,7 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
DRIVER_NAME, dev);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "comedi%d: error! "
|
||||
"unable to allocate irq %u\n", dev->minor, irq);
|
||||
"unable to allocate irq %u\n", dev->minor, irq);
|
||||
return ret;
|
||||
} else {
|
||||
dev->irq = irq;
|
||||
@@ -1545,7 +1559,7 @@ static int pci224_detach(struct comedi_device *dev)
|
||||
}
|
||||
if (dev->board_name) {
|
||||
printk(KERN_INFO "comedi%d: %s removed\n",
|
||||
dev->minor, dev->board_name);
|
||||
dev->minor, dev->board_name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -97,7 +97,8 @@ union encvaluetype {
|
||||
|
||||
#define C6XDIGIO_TIME_OUT 20
|
||||
|
||||
static int c6xdigio_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int c6xdigio_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int c6xdigio_detach(struct comedi_device *dev);
|
||||
struct comedi_driver driver_c6xdigio = {
|
||||
.driver_name = "c6xdigio",
|
||||
@@ -114,28 +115,28 @@ static void C6X_pwmInit(unsigned long baseAddr)
|
||||
|
||||
WriteByteToHwPort(baseAddr, 0x70);
|
||||
while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0)
|
||||
&& (timeout < C6XDIGIO_TIME_OUT)) {
|
||||
&& (timeout < C6XDIGIO_TIME_OUT)) {
|
||||
timeout++;
|
||||
}
|
||||
|
||||
WriteByteToHwPort(baseAddr, 0x74);
|
||||
timeout = 0;
|
||||
while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0x80)
|
||||
&& (timeout < C6XDIGIO_TIME_OUT)) {
|
||||
&& (timeout < C6XDIGIO_TIME_OUT)) {
|
||||
timeout++;
|
||||
}
|
||||
|
||||
WriteByteToHwPort(baseAddr, 0x70);
|
||||
timeout = 0;
|
||||
while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0x0)
|
||||
&& (timeout < C6XDIGIO_TIME_OUT)) {
|
||||
&& (timeout < C6XDIGIO_TIME_OUT)) {
|
||||
timeout++;
|
||||
}
|
||||
|
||||
WriteByteToHwPort(baseAddr, 0x0);
|
||||
timeout = 0;
|
||||
while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0x80)
|
||||
&& (timeout < C6XDIGIO_TIME_OUT)) {
|
||||
&& (timeout < C6XDIGIO_TIME_OUT)) {
|
||||
timeout++;
|
||||
}
|
||||
|
||||
@@ -315,38 +316,41 @@ static void C6X_encResetAll(unsigned long baseAddr)
|
||||
|
||||
WriteByteToHwPort(baseAddr, 0x68);
|
||||
while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0)
|
||||
&& (timeout < C6XDIGIO_TIME_OUT)) {
|
||||
&& (timeout < C6XDIGIO_TIME_OUT)) {
|
||||
timeout++;
|
||||
}
|
||||
WriteByteToHwPort(baseAddr, 0x6C);
|
||||
timeout = 0;
|
||||
while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0x80)
|
||||
&& (timeout < C6XDIGIO_TIME_OUT)) {
|
||||
&& (timeout < C6XDIGIO_TIME_OUT)) {
|
||||
timeout++;
|
||||
}
|
||||
WriteByteToHwPort(baseAddr, 0x68);
|
||||
timeout = 0;
|
||||
while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0x0)
|
||||
&& (timeout < C6XDIGIO_TIME_OUT)) {
|
||||
&& (timeout < C6XDIGIO_TIME_OUT)) {
|
||||
timeout++;
|
||||
}
|
||||
WriteByteToHwPort(baseAddr, 0x0);
|
||||
timeout = 0;
|
||||
while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0x80)
|
||||
&& (timeout < C6XDIGIO_TIME_OUT)) {
|
||||
&& (timeout < C6XDIGIO_TIME_OUT)) {
|
||||
timeout++;
|
||||
}
|
||||
}
|
||||
|
||||
static int c6xdigio_pwmo_insn_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
printk("c6xdigio_pwmo_insn_read %x\n", insn->n);
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
static int c6xdigio_pwmo_insn_write(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
int i;
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
@@ -375,12 +379,13 @@ static int c6xdigio_pwmo_insn_write(struct comedi_device *dev,
|
||||
/* { */
|
||||
/* int i; */
|
||||
/* int chan = CR_CHAN(insn->chanspec); */
|
||||
/* *//* C6X_encResetAll( dev->iobase ); */
|
||||
/* *//* return insn->n; */
|
||||
/* *//* C6X_encResetAll( dev->iobase ); */
|
||||
/* *//* return insn->n; */
|
||||
/* } */
|
||||
|
||||
static int c6xdigio_ei_insn_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
/* printk("c6xdigio_ei__insn_read %x\n", insn->n); */
|
||||
int n;
|
||||
@@ -415,9 +420,9 @@ static void board_init(struct comedi_device *dev)
|
||||
|
||||
static const struct pnp_device_id c6xdigio_pnp_tbl[] = {
|
||||
/* Standard LPT Printer Port */
|
||||
{.id = "PNP0400", .driver_data = 0},
|
||||
{.id = "PNP0400",.driver_data = 0},
|
||||
/* ECP Printer Port */
|
||||
{.id = "PNP0401", .driver_data = 0},
|
||||
{.id = "PNP0401",.driver_data = 0},
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -426,7 +431,8 @@ static struct pnp_driver c6xdigio_pnp_driver = {
|
||||
.id_table = c6xdigio_pnp_tbl,
|
||||
};
|
||||
|
||||
static int c6xdigio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
static int c6xdigio_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it)
|
||||
{
|
||||
int result = 0;
|
||||
unsigned long iobase;
|
||||
@@ -478,7 +484,7 @@ static int c6xdigio_attach(struct comedi_device *dev, struct comedi_devconfig *i
|
||||
s->range_table = &range_unknown;
|
||||
|
||||
/* s = dev->subdevices + 2; */
|
||||
/* pwm output subdevice */
|
||||
/* pwm output subdevice */
|
||||
/* s->type = COMEDI_SUBD_COUNTER; // Not sure what to put here */
|
||||
/* s->subdev_flags = SDF_WRITEABLE; */
|
||||
/* s->n_chan = 1; */
|
||||
|
||||
@@ -62,23 +62,23 @@ struct das16cs_board {
|
||||
};
|
||||
static const struct das16cs_board das16cs_boards[] = {
|
||||
{
|
||||
.device_id = 0x0000,/* unknown */
|
||||
.name = "PC-CARD DAS16/16",
|
||||
.n_ao_chans = 0,
|
||||
},
|
||||
.device_id = 0x0000, /* unknown */
|
||||
.name = "PC-CARD DAS16/16",
|
||||
.n_ao_chans = 0,
|
||||
},
|
||||
{
|
||||
.device_id = 0x0039,
|
||||
.name = "PC-CARD DAS16/16-AO",
|
||||
.n_ao_chans = 2,
|
||||
},
|
||||
.device_id = 0x0039,
|
||||
.name = "PC-CARD DAS16/16-AO",
|
||||
.n_ao_chans = 2,
|
||||
},
|
||||
{
|
||||
.device_id = 0x4009,
|
||||
.name = "PCM-DAS16s/16",
|
||||
.n_ao_chans = 0,
|
||||
},
|
||||
.device_id = 0x4009,
|
||||
.name = "PCM-DAS16s/16",
|
||||
.n_ao_chans = 0,
|
||||
},
|
||||
};
|
||||
|
||||
#define n_boards (sizeof(das16cs_boards)/sizeof(das16cs_boards[0]))
|
||||
#define n_boards ARRAY_SIZE(das16cs_boards)
|
||||
#define thisboard ((const struct das16cs_board *)dev->board_ptr)
|
||||
|
||||
struct das16cs_private {
|
||||
@@ -90,7 +90,8 @@ struct das16cs_private {
|
||||
};
|
||||
#define devpriv ((struct das16cs_private *)dev->private)
|
||||
|
||||
static int das16cs_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int das16cs_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int das16cs_detach(struct comedi_device *dev);
|
||||
static struct comedi_driver driver_das16cs = {
|
||||
.driver_name = "cb_das16_cs",
|
||||
@@ -102,31 +103,43 @@ static struct comedi_driver driver_das16cs = {
|
||||
static struct pcmcia_device *cur_dev = NULL;
|
||||
|
||||
static const struct comedi_lrange das16cs_ai_range = { 4, {
|
||||
RANGE(-10, 10),
|
||||
RANGE(-5, 5),
|
||||
RANGE(-2.5, 2.5),
|
||||
RANGE(-1.25, 1.25),
|
||||
}
|
||||
RANGE(-10, 10),
|
||||
RANGE(-5, 5),
|
||||
RANGE(-2.5, 2.5),
|
||||
RANGE(-1.25, 1.25),
|
||||
}
|
||||
};
|
||||
|
||||
static irqreturn_t das16cs_interrupt(int irq, void *d);
|
||||
static int das16cs_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int das16cs_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
|
||||
static int das16cs_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd);
|
||||
static int das16cs_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int das16cs_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int das16cs_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int das16cs_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int das16cs_timer_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int das16cs_timer_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int das16cs_ai_rinsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int das16cs_ai_cmd(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s);
|
||||
static int das16cs_ai_cmdtest(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd);
|
||||
static int das16cs_ao_winsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int das16cs_ao_rinsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int das16cs_dio_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int das16cs_dio_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
static int das16cs_timer_insn_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
static int das16cs_timer_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
|
||||
static int get_prodid(struct comedi_device *dev, struct pcmcia_device *link)
|
||||
{
|
||||
@@ -140,15 +153,15 @@ static int get_prodid(struct comedi_device *dev, struct pcmcia_device *link)
|
||||
tuple.DesiredTuple = CISTPL_MANFID;
|
||||
tuple.Attributes = TUPLE_RETURN_COMMON;
|
||||
if ((pcmcia_get_first_tuple(link, &tuple) == 0) &&
|
||||
(pcmcia_get_tuple_data(link, &tuple) == 0)) {
|
||||
(pcmcia_get_tuple_data(link, &tuple) == 0)) {
|
||||
prodid = le16_to_cpu(buf[1]);
|
||||
}
|
||||
|
||||
return prodid;
|
||||
}
|
||||
|
||||
static const struct das16cs_board *das16cs_probe(struct comedi_device * dev,
|
||||
struct pcmcia_device *link)
|
||||
static const struct das16cs_board *das16cs_probe(struct comedi_device *dev,
|
||||
struct pcmcia_device *link)
|
||||
{
|
||||
int id;
|
||||
int i;
|
||||
@@ -166,7 +179,8 @@ static const struct das16cs_board *das16cs_probe(struct comedi_device * dev,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int das16cs_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
static int das16cs_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it)
|
||||
{
|
||||
struct pcmcia_device *link;
|
||||
struct comedi_subdevice *s;
|
||||
@@ -287,8 +301,9 @@ static irqreturn_t das16cs_interrupt(int irq, void *d)
|
||||
* "instructions" read/write data in "one-shot" or "software-triggered"
|
||||
* mode.
|
||||
*/
|
||||
static int das16cs_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int das16cs_ai_rinsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int i;
|
||||
int to;
|
||||
@@ -334,8 +349,9 @@ static int das16cs_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int das16cs_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd)
|
||||
static int das16cs_ai_cmdtest(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd)
|
||||
{
|
||||
int err = 0;
|
||||
int tmp;
|
||||
@@ -381,7 +397,7 @@ static int das16cs_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
|
||||
|
||||
/* note that mutual compatiblity is not an issue here */
|
||||
if (cmd->scan_begin_src != TRIG_TIMER &&
|
||||
cmd->scan_begin_src != TRIG_EXT)
|
||||
cmd->scan_begin_src != TRIG_EXT)
|
||||
err++;
|
||||
if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
|
||||
err++;
|
||||
@@ -463,7 +479,8 @@ static int das16cs_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
|
||||
|
||||
tmp = cmd->scan_begin_arg;
|
||||
i8253_cascade_ns_to_timer(100, &div1, &div2,
|
||||
&cmd->scan_begin_arg, cmd->flags & TRIG_ROUND_MASK);
|
||||
&cmd->scan_begin_arg,
|
||||
cmd->flags & TRIG_ROUND_MASK);
|
||||
if (tmp != cmd->scan_begin_arg)
|
||||
err++;
|
||||
}
|
||||
@@ -472,14 +489,15 @@ static int das16cs_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
|
||||
|
||||
tmp = cmd->convert_arg;
|
||||
i8253_cascade_ns_to_timer(100, &div1, &div2,
|
||||
&cmd->scan_begin_arg, cmd->flags & TRIG_ROUND_MASK);
|
||||
&cmd->scan_begin_arg,
|
||||
cmd->flags & TRIG_ROUND_MASK);
|
||||
if (tmp != cmd->convert_arg)
|
||||
err++;
|
||||
if (cmd->scan_begin_src == TRIG_TIMER &&
|
||||
cmd->scan_begin_arg <
|
||||
cmd->convert_arg * cmd->scan_end_arg) {
|
||||
cmd->scan_begin_arg <
|
||||
cmd->convert_arg * cmd->scan_end_arg) {
|
||||
cmd->scan_begin_arg =
|
||||
cmd->convert_arg * cmd->scan_end_arg;
|
||||
cmd->convert_arg * cmd->scan_end_arg;
|
||||
err++;
|
||||
}
|
||||
}
|
||||
@@ -490,8 +508,9 @@ static int das16cs_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int das16cs_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int das16cs_ao_winsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int i;
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
@@ -536,8 +555,9 @@ static int das16cs_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *
|
||||
|
||||
/* AO subdevices should have a read insn as well as a write insn.
|
||||
* Usually this means copying a value stored in devpriv. */
|
||||
static int das16cs_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int das16cs_ao_rinsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int i;
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
@@ -553,8 +573,9 @@ static int das16cs_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *
|
||||
* useful to applications if you implement the insn_bits interface.
|
||||
* This allows packed reading/writing of the DIO channels. The
|
||||
* comedi core can convert between insn_bits and insn_read/write */
|
||||
static int das16cs_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int das16cs_dio_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
if (insn->n != 2)
|
||||
return -EINVAL;
|
||||
@@ -573,8 +594,9 @@ static int das16cs_dio_insn_bits(struct comedi_device *dev, struct comedi_subdev
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int das16cs_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int das16cs_dio_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
int bits;
|
||||
@@ -593,8 +615,7 @@ static int das16cs_dio_insn_config(struct comedi_device *dev, struct comedi_subd
|
||||
break;
|
||||
case INSN_CONFIG_DIO_QUERY:
|
||||
data[1] =
|
||||
(s->
|
||||
io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
|
||||
(s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
|
||||
return insn->n;
|
||||
break;
|
||||
default:
|
||||
@@ -611,14 +632,17 @@ static int das16cs_dio_insn_config(struct comedi_device *dev, struct comedi_subd
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
static int das16cs_timer_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int das16cs_timer_insn_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int das16cs_timer_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int das16cs_timer_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -650,7 +674,7 @@ static int pc_debug = PCMCIA_DEBUG;
|
||||
module_param(pc_debug, int, 0644);
|
||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
|
||||
static char *version =
|
||||
"cb_das16_cs.c pcmcia code (David Schleef), modified from dummy_cs.c 1.31 2001/08/24 12:13:13 (David Hinds)";
|
||||
"cb_das16_cs.c pcmcia code (David Schleef), modified from dummy_cs.c 1.31 2001/08/24 12:13:13 (David Hinds)";
|
||||
#else
|
||||
#define DEBUG(n, args...)
|
||||
#endif
|
||||
@@ -739,7 +763,7 @@ static void das16cs_pcmcia_detach(struct pcmcia_device *link)
|
||||
DEBUG(0, "das16cs_pcmcia_detach(0x%p)\n", link);
|
||||
|
||||
if (link->dev_node) {
|
||||
((struct local_info_t *) link->priv)->stop = 1;
|
||||
((struct local_info_t *)link->priv)->stop = 1;
|
||||
das16cs_pcmcia_release(link);
|
||||
}
|
||||
/* This points to the parent struct local_info_t struct */
|
||||
@@ -853,7 +877,7 @@ static void das16cs_pcmcia_config(struct pcmcia_device *link)
|
||||
/* If we got this far, we're cool! */
|
||||
break;
|
||||
|
||||
next_entry:
|
||||
next_entry:
|
||||
last_fn = GetNextTuple;
|
||||
|
||||
last_ret = pcmcia_get_next_tuple(link, &tuple);
|
||||
@@ -893,20 +917,20 @@ static void das16cs_pcmcia_config(struct pcmcia_device *link)
|
||||
|
||||
/* Finally, report what we've done */
|
||||
printk(KERN_INFO "%s: index 0x%02x",
|
||||
dev->node.dev_name, link->conf.ConfigIndex);
|
||||
dev->node.dev_name, link->conf.ConfigIndex);
|
||||
if (link->conf.Attributes & CONF_ENABLE_IRQ)
|
||||
printk(", irq %u", link->irq.AssignedIRQ);
|
||||
if (link->io.NumPorts1)
|
||||
printk(", io 0x%04x-0x%04x", link->io.BasePort1,
|
||||
link->io.BasePort1 + link->io.NumPorts1 - 1);
|
||||
link->io.BasePort1 + link->io.NumPorts1 - 1);
|
||||
if (link->io.NumPorts2)
|
||||
printk(" & 0x%04x-0x%04x", link->io.BasePort2,
|
||||
link->io.BasePort2 + link->io.NumPorts2 - 1);
|
||||
link->io.BasePort2 + link->io.NumPorts2 - 1);
|
||||
printk("\n");
|
||||
|
||||
return;
|
||||
|
||||
cs_failed:
|
||||
cs_failed:
|
||||
cs_error(link, last_fn, last_ret);
|
||||
das16cs_pcmcia_release(link);
|
||||
} /* das16cs_pcmcia_config */
|
||||
@@ -953,7 +977,7 @@ struct pcmcia_driver das16cs_driver = {
|
||||
.id_table = das16cs_id_table,
|
||||
.owner = THIS_MODULE,
|
||||
.drv = {
|
||||
.name = dev_info,
|
||||
.name = dev_info,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -115,13 +115,13 @@ Please report success/failure with other different cards to
|
||||
static const struct comedi_lrange cb_pcidda_ranges = {
|
||||
6,
|
||||
{
|
||||
BIP_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(2.5),
|
||||
UNI_RANGE(10),
|
||||
UNI_RANGE(5),
|
||||
UNI_RANGE(2.5),
|
||||
}
|
||||
BIP_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(2.5),
|
||||
UNI_RANGE(10),
|
||||
UNI_RANGE(5),
|
||||
UNI_RANGE(2.5),
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -147,63 +147,64 @@ struct cb_pcidda_board {
|
||||
|
||||
static const struct cb_pcidda_board cb_pcidda_boards[] = {
|
||||
{
|
||||
.name = "pci-dda02/12",
|
||||
.status = 1,
|
||||
.device_id = 0x20,
|
||||
.ao_chans = 2,
|
||||
.ao_bits = 12,
|
||||
.ranges = &cb_pcidda_ranges,
|
||||
},
|
||||
.name = "pci-dda02/12",
|
||||
.status = 1,
|
||||
.device_id = 0x20,
|
||||
.ao_chans = 2,
|
||||
.ao_bits = 12,
|
||||
.ranges = &cb_pcidda_ranges,
|
||||
},
|
||||
{
|
||||
.name = "pci-dda04/12",
|
||||
.status = 1,
|
||||
.device_id = 0x21,
|
||||
.ao_chans = 4,
|
||||
.ao_bits = 12,
|
||||
.ranges = &cb_pcidda_ranges,
|
||||
},
|
||||
.name = "pci-dda04/12",
|
||||
.status = 1,
|
||||
.device_id = 0x21,
|
||||
.ao_chans = 4,
|
||||
.ao_bits = 12,
|
||||
.ranges = &cb_pcidda_ranges,
|
||||
},
|
||||
{
|
||||
.name = "pci-dda08/12",
|
||||
.status = 0,
|
||||
.device_id = 0x22,
|
||||
.ao_chans = 8,
|
||||
.ao_bits = 12,
|
||||
.ranges = &cb_pcidda_ranges,
|
||||
},
|
||||
.name = "pci-dda08/12",
|
||||
.status = 0,
|
||||
.device_id = 0x22,
|
||||
.ao_chans = 8,
|
||||
.ao_bits = 12,
|
||||
.ranges = &cb_pcidda_ranges,
|
||||
},
|
||||
{
|
||||
.name = "pci-dda02/16",
|
||||
.status = 2,
|
||||
.device_id = 0x23,
|
||||
.ao_chans = 2,
|
||||
.ao_bits = 16,
|
||||
.ranges = &cb_pcidda_ranges,
|
||||
},
|
||||
.name = "pci-dda02/16",
|
||||
.status = 2,
|
||||
.device_id = 0x23,
|
||||
.ao_chans = 2,
|
||||
.ao_bits = 16,
|
||||
.ranges = &cb_pcidda_ranges,
|
||||
},
|
||||
{
|
||||
.name = "pci-dda04/16",
|
||||
.status = 2,
|
||||
.device_id = 0x24,
|
||||
.ao_chans = 4,
|
||||
.ao_bits = 16,
|
||||
.ranges = &cb_pcidda_ranges,
|
||||
},
|
||||
.name = "pci-dda04/16",
|
||||
.status = 2,
|
||||
.device_id = 0x24,
|
||||
.ao_chans = 4,
|
||||
.ao_bits = 16,
|
||||
.ranges = &cb_pcidda_ranges,
|
||||
},
|
||||
{
|
||||
.name = "pci-dda08/16",
|
||||
.status = 0,
|
||||
.device_id = 0x25,
|
||||
.ao_chans = 8,
|
||||
.ao_bits = 16,
|
||||
.ranges = &cb_pcidda_ranges,
|
||||
},
|
||||
.name = "pci-dda08/16",
|
||||
.status = 0,
|
||||
.device_id = 0x25,
|
||||
.ao_chans = 8,
|
||||
.ao_bits = 16,
|
||||
.ranges = &cb_pcidda_ranges,
|
||||
},
|
||||
};
|
||||
|
||||
static DEFINE_PCI_DEVICE_TABLE(cb_pcidda_pci_table) = {
|
||||
{PCI_VENDOR_ID_CB, 0x0020, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_CB, 0x0021, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_CB, 0x0022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_CB, 0x0023, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_CB, 0x0024, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_CB, 0x0025, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{0}
|
||||
{
|
||||
PCI_VENDOR_ID_CB, 0x0020, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_CB, 0x0021, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_CB, 0x0022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_CB, 0x0023, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_CB, 0x0024, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_CB, 0x0025, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
0}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, cb_pcidda_pci_table);
|
||||
@@ -239,11 +240,13 @@ struct cb_pcidda_private {
|
||||
*/
|
||||
#define devpriv ((struct cb_pcidda_private *)dev->private)
|
||||
|
||||
static int cb_pcidda_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int cb_pcidda_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int cb_pcidda_detach(struct comedi_device *dev);
|
||||
/* static int cb_pcidda_ai_rinsn(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data); */
|
||||
static int cb_pcidda_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int cb_pcidda_ao_winsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
/* static int cb_pcidda_ai_cmd(struct comedi_device *dev, struct *comedi_subdevice *s);*/
|
||||
/* static int cb_pcidda_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd); */
|
||||
@@ -251,11 +254,11 @@ static int cb_pcidda_ao_winsn(struct comedi_device *dev, struct comedi_subdevice
|
||||
|
||||
static unsigned int cb_pcidda_serial_in(struct comedi_device *dev);
|
||||
static void cb_pcidda_serial_out(struct comedi_device *dev, unsigned int value,
|
||||
unsigned int num_bits);
|
||||
unsigned int num_bits);
|
||||
static unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev,
|
||||
unsigned int address);
|
||||
unsigned int address);
|
||||
static void cb_pcidda_calibrate(struct comedi_device *dev, unsigned int channel,
|
||||
unsigned int range);
|
||||
unsigned int range);
|
||||
|
||||
/*
|
||||
* The struct comedi_driver structure tells the Comedi core module
|
||||
@@ -274,7 +277,8 @@ static struct comedi_driver driver_cb_pcidda = {
|
||||
* Attach is called by the Comedi core to configure the driver
|
||||
* for a particular board.
|
||||
*/
|
||||
static int cb_pcidda_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
static int cb_pcidda_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it)
|
||||
{
|
||||
struct comedi_subdevice *s;
|
||||
struct pci_dev *pcidev;
|
||||
@@ -294,29 +298,29 @@ static int cb_pcidda_attach(struct comedi_device *dev, struct comedi_devconfig *
|
||||
printk("\n");
|
||||
|
||||
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)) {
|
||||
pcidev != NULL;
|
||||
pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
|
||||
if (pcidev->vendor == PCI_VENDOR_ID_CB) {
|
||||
if (it->options[0] || it->options[1]) {
|
||||
if (pcidev->bus->number != it->options[0] ||
|
||||
PCI_SLOT(pcidev->devfn) !=
|
||||
it->options[1]) {
|
||||
PCI_SLOT(pcidev->devfn) != it->options[1]) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
for (index = 0; index < N_BOARDS; index++) {
|
||||
if (cb_pcidda_boards[index].device_id ==
|
||||
pcidev->device) {
|
||||
pcidev->device) {
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!pcidev) {
|
||||
printk("Not a ComputerBoards/MeasurementComputing card on requested position\n");
|
||||
printk
|
||||
("Not a ComputerBoards/MeasurementComputing card on requested position\n");
|
||||
return -EIO;
|
||||
}
|
||||
found:
|
||||
found:
|
||||
devpriv->pci_dev = pcidev;
|
||||
dev->board_ptr = cb_pcidda_boards + index;
|
||||
/* "thisboard" macro can be used from here. */
|
||||
@@ -326,7 +330,8 @@ static int cb_pcidda_attach(struct comedi_device *dev, struct comedi_devconfig *
|
||||
* Enable PCI device and request regions.
|
||||
*/
|
||||
if (comedi_pci_enable(pcidev, thisboard->name)) {
|
||||
printk("cb_pcidda: failed to enable PCI device and request regions\n");
|
||||
printk
|
||||
("cb_pcidda: failed to enable PCI device and request regions\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@@ -334,14 +339,17 @@ static int cb_pcidda_attach(struct comedi_device *dev, struct comedi_devconfig *
|
||||
* Allocate the I/O ports.
|
||||
*/
|
||||
devpriv->digitalio =
|
||||
pci_resource_start(devpriv->pci_dev, DIGITALIO_BADRINDEX);
|
||||
pci_resource_start(devpriv->pci_dev, DIGITALIO_BADRINDEX);
|
||||
devpriv->dac = pci_resource_start(devpriv->pci_dev, DAC_BADRINDEX);
|
||||
|
||||
/*
|
||||
* Warn about the status of the driver.
|
||||
*/
|
||||
if (thisboard->status == 2)
|
||||
printk("WARNING: DRIVER FOR THIS BOARD NOT CHECKED WITH MANUAL. " "WORKS ASSUMING FULL COMPATIBILITY WITH PCI-DDA08/12. " "PLEASE REPORT USAGE TO <ivanmr@altavista.com>.\n");
|
||||
printk
|
||||
("WARNING: DRIVER FOR THIS BOARD NOT CHECKED WITH MANUAL. "
|
||||
"WORKS ASSUMING FULL COMPATIBILITY WITH PCI-DDA08/12. "
|
||||
"PLEASE REPORT USAGE TO <ivanmr@altavista.com>.\n");
|
||||
|
||||
/*
|
||||
* Initialize dev->board_name.
|
||||
@@ -423,7 +431,8 @@ static int cb_pcidda_detach(struct comedi_device *dev)
|
||||
* I will program this later... ;-)
|
||||
*/
|
||||
#if 0
|
||||
static int cb_pcidda_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
static int cb_pcidda_ai_cmd(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
printk("cb_pcidda_ai_cmd\n");
|
||||
printk("subdev: %d\n", cmd->subdev);
|
||||
@@ -442,8 +451,9 @@ static int cb_pcidda_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static int cb_pcidda_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd)
|
||||
static int cb_pcidda_ai_cmdtest(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd)
|
||||
{
|
||||
int err = 0;
|
||||
int tmp;
|
||||
@@ -489,7 +499,7 @@ static int cb_pcidda_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevi
|
||||
|
||||
/* note that mutual compatiblity is not an issue here */
|
||||
if (cmd->scan_begin_src != TRIG_TIMER
|
||||
&& cmd->scan_begin_src != TRIG_EXT)
|
||||
&& cmd->scan_begin_src != TRIG_EXT)
|
||||
err++;
|
||||
if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
|
||||
err++;
|
||||
@@ -569,21 +579,21 @@ static int cb_pcidda_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevi
|
||||
if (cmd->scan_begin_src == TRIG_TIMER) {
|
||||
tmp = cmd->scan_begin_arg;
|
||||
cb_pcidda_ns_to_timer(&cmd->scan_begin_arg,
|
||||
cmd->flags & TRIG_ROUND_MASK);
|
||||
cmd->flags & TRIG_ROUND_MASK);
|
||||
if (tmp != cmd->scan_begin_arg)
|
||||
err++;
|
||||
}
|
||||
if (cmd->convert_src == TRIG_TIMER) {
|
||||
tmp = cmd->convert_arg;
|
||||
cb_pcidda_ns_to_timer(&cmd->convert_arg,
|
||||
cmd->flags & TRIG_ROUND_MASK);
|
||||
cmd->flags & TRIG_ROUND_MASK);
|
||||
if (tmp != cmd->convert_arg)
|
||||
err++;
|
||||
if (cmd->scan_begin_src == TRIG_TIMER &&
|
||||
cmd->scan_begin_arg <
|
||||
cmd->convert_arg * cmd->scan_end_arg) {
|
||||
cmd->scan_begin_arg <
|
||||
cmd->convert_arg * cmd->scan_end_arg) {
|
||||
cmd->scan_begin_arg =
|
||||
cmd->convert_arg * cmd->scan_end_arg;
|
||||
cmd->convert_arg * cmd->scan_end_arg;
|
||||
err++;
|
||||
}
|
||||
}
|
||||
@@ -608,8 +618,9 @@ static int cb_pcidda_ns_to_timer(unsigned int *ns, int round)
|
||||
}
|
||||
#endif
|
||||
|
||||
static int cb_pcidda_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int cb_pcidda_ao_winsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
unsigned int command;
|
||||
unsigned int channel, range;
|
||||
@@ -676,7 +687,7 @@ static unsigned int cb_pcidda_serial_in(struct comedi_device *dev)
|
||||
|
||||
/* lowlevel write to eeprom/dac */
|
||||
static void cb_pcidda_serial_out(struct comedi_device *dev, unsigned int value,
|
||||
unsigned int num_bits)
|
||||
unsigned int num_bits)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -692,7 +703,7 @@ static void cb_pcidda_serial_out(struct comedi_device *dev, unsigned int value,
|
||||
|
||||
/* reads a 16 bit value from board's eeprom */
|
||||
static unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev,
|
||||
unsigned int address)
|
||||
unsigned int address)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int cal2_bits;
|
||||
@@ -725,8 +736,9 @@ static unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev,
|
||||
}
|
||||
|
||||
/* writes to 8 bit calibration dacs */
|
||||
static void cb_pcidda_write_caldac(struct comedi_device *dev, unsigned int caldac,
|
||||
unsigned int channel, unsigned int value)
|
||||
static void cb_pcidda_write_caldac(struct comedi_device *dev,
|
||||
unsigned int caldac, unsigned int channel,
|
||||
unsigned int value)
|
||||
{
|
||||
unsigned int cal2_bits;
|
||||
unsigned int i;
|
||||
@@ -787,14 +799,14 @@ static unsigned int fine_offset_channel(unsigned int ao_channel)
|
||||
|
||||
/* returns eeprom address that provides offset for given ao channel and range */
|
||||
static unsigned int offset_eeprom_address(unsigned int ao_channel,
|
||||
unsigned int range)
|
||||
unsigned int range)
|
||||
{
|
||||
return 0x7 + 2 * range + 12 * ao_channel;
|
||||
}
|
||||
|
||||
/* returns eeprom address that provides gain calibration for given ao channel and range */
|
||||
static unsigned int gain_eeprom_address(unsigned int ao_channel,
|
||||
unsigned int range)
|
||||
unsigned int range)
|
||||
{
|
||||
return 0x8 + 2 * range + 12 * ao_channel;
|
||||
}
|
||||
@@ -813,7 +825,7 @@ static unsigned int eeprom_fine_byte(unsigned int word)
|
||||
|
||||
/* set caldacs to eeprom values for given channel and range */
|
||||
static void cb_pcidda_calibrate(struct comedi_device *dev, unsigned int channel,
|
||||
unsigned int range)
|
||||
unsigned int range)
|
||||
{
|
||||
unsigned int coarse_offset, fine_offset, coarse_gain, fine_gain;
|
||||
|
||||
@@ -822,27 +834,27 @@ static void cb_pcidda_calibrate(struct comedi_device *dev, unsigned int channel,
|
||||
|
||||
/* get values from eeprom data */
|
||||
coarse_offset =
|
||||
eeprom_coarse_byte(devpriv->
|
||||
eeprom_data[offset_eeprom_address(channel, range)]);
|
||||
eeprom_coarse_byte(devpriv->eeprom_data
|
||||
[offset_eeprom_address(channel, range)]);
|
||||
fine_offset =
|
||||
eeprom_fine_byte(devpriv->
|
||||
eeprom_data[offset_eeprom_address(channel, range)]);
|
||||
eeprom_fine_byte(devpriv->eeprom_data
|
||||
[offset_eeprom_address(channel, range)]);
|
||||
coarse_gain =
|
||||
eeprom_coarse_byte(devpriv->
|
||||
eeprom_data[gain_eeprom_address(channel, range)]);
|
||||
eeprom_coarse_byte(devpriv->eeprom_data
|
||||
[gain_eeprom_address(channel, range)]);
|
||||
fine_gain =
|
||||
eeprom_fine_byte(devpriv->
|
||||
eeprom_data[gain_eeprom_address(channel, range)]);
|
||||
eeprom_fine_byte(devpriv->eeprom_data
|
||||
[gain_eeprom_address(channel, range)]);
|
||||
|
||||
/* set caldacs */
|
||||
cb_pcidda_write_caldac(dev, caldac_number(channel),
|
||||
coarse_offset_channel(channel), coarse_offset);
|
||||
coarse_offset_channel(channel), coarse_offset);
|
||||
cb_pcidda_write_caldac(dev, caldac_number(channel),
|
||||
fine_offset_channel(channel), fine_offset);
|
||||
fine_offset_channel(channel), fine_offset);
|
||||
cb_pcidda_write_caldac(dev, caldac_number(channel),
|
||||
coarse_gain_channel(channel), coarse_gain);
|
||||
coarse_gain_channel(channel), coarse_gain);
|
||||
cb_pcidda_write_caldac(dev, caldac_number(channel),
|
||||
fine_gain_channel(channel), fine_gain);
|
||||
fine_gain_channel(channel), fine_gain);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -63,23 +63,23 @@ struct pcidio_board {
|
||||
|
||||
static const struct pcidio_board pcidio_boards[] = {
|
||||
{
|
||||
.name = "pci-dio24",
|
||||
.n_8255 = 1,
|
||||
.pcicontroler_badrindex = 1,
|
||||
.dioregs_badrindex = 2,
|
||||
},
|
||||
.name = "pci-dio24",
|
||||
.n_8255 = 1,
|
||||
.pcicontroler_badrindex = 1,
|
||||
.dioregs_badrindex = 2,
|
||||
},
|
||||
{
|
||||
.name = "pci-dio24h",
|
||||
.n_8255 = 1,
|
||||
.pcicontroler_badrindex = 1,
|
||||
.dioregs_badrindex = 2,
|
||||
},
|
||||
.name = "pci-dio24h",
|
||||
.n_8255 = 1,
|
||||
.pcicontroler_badrindex = 1,
|
||||
.dioregs_badrindex = 2,
|
||||
},
|
||||
{
|
||||
.name = "pci-dio48h",
|
||||
.n_8255 = 2,
|
||||
.pcicontroler_badrindex = 0,
|
||||
.dioregs_badrindex = 1,
|
||||
},
|
||||
.name = "pci-dio48h",
|
||||
.n_8255 = 2,
|
||||
.pcicontroler_badrindex = 0,
|
||||
.dioregs_badrindex = 1,
|
||||
},
|
||||
};
|
||||
|
||||
/* This is used by modprobe to translate PCI IDs to drivers. Should
|
||||
@@ -87,10 +87,11 @@ static const struct pcidio_board pcidio_boards[] = {
|
||||
/* Please add your PCI vendor ID to comedidev.h, and it will be forwarded
|
||||
* upstream. */
|
||||
static DEFINE_PCI_DEVICE_TABLE(pcidio_pci_table) = {
|
||||
{PCI_VENDOR_ID_CB, 0x0028, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_CB, 0x0014, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_CB, 0x000b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{0}
|
||||
{
|
||||
PCI_VENDOR_ID_CB, 0x0028, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_CB, 0x0014, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_CB, 0x000b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
0}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, pcidio_pci_table);
|
||||
@@ -127,7 +128,8 @@ struct pcidio_private {
|
||||
* the board, and also about the kernel module that contains
|
||||
* the device code.
|
||||
*/
|
||||
static int pcidio_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int pcidio_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int pcidio_detach(struct comedi_device *dev);
|
||||
static struct comedi_driver driver_cb_pcidio = {
|
||||
.driver_name = "cb_pcidio",
|
||||
@@ -197,15 +199,13 @@ static int pcidio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
*/
|
||||
|
||||
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)) {
|
||||
pcidev != NULL;
|
||||
pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
|
||||
/* is it not a computer boards card? */
|
||||
if (pcidev->vendor != PCI_VENDOR_ID_CB)
|
||||
continue;
|
||||
/* loop through cards supported by this driver */
|
||||
for (index = 0;
|
||||
index < ARRAY_SIZE(pcidio_boards);
|
||||
index++) {
|
||||
for (index = 0; index < ARRAY_SIZE(pcidio_boards); index++) {
|
||||
if (pcidio_pci_table[index].device != pcidev->device)
|
||||
continue;
|
||||
|
||||
@@ -213,8 +213,7 @@ static int pcidio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
if (it->options[0] || it->options[1]) {
|
||||
/* are we on the wrong bus/slot? */
|
||||
if (pcidev->bus->number != it->options[0] ||
|
||||
PCI_SLOT(pcidev->devfn) !=
|
||||
it->options[1]) {
|
||||
PCI_SLOT(pcidev->devfn) != it->options[1]) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -224,10 +223,10 @@ static int pcidio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
}
|
||||
|
||||
printk("No supported ComputerBoards/MeasurementComputing card found on "
|
||||
"requested position\n");
|
||||
"requested position\n");
|
||||
return -EIO;
|
||||
|
||||
found:
|
||||
found:
|
||||
|
||||
/*
|
||||
* Initialize dev->board_name. Note that we can use the "thisboard"
|
||||
@@ -237,16 +236,17 @@ static int pcidio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
|
||||
devpriv->pci_dev = pcidev;
|
||||
printk("Found %s on bus %i, slot %i\n", thisboard->name,
|
||||
devpriv->pci_dev->bus->number,
|
||||
PCI_SLOT(devpriv->pci_dev->devfn));
|
||||
devpriv->pci_dev->bus->number,
|
||||
PCI_SLOT(devpriv->pci_dev->devfn));
|
||||
if (comedi_pci_enable(pcidev, thisboard->name)) {
|
||||
printk("cb_pcidio: failed to enable PCI device and request regions\n");
|
||||
printk
|
||||
("cb_pcidio: failed to enable PCI device and request regions\n");
|
||||
return -EIO;
|
||||
}
|
||||
devpriv->dio_reg_base
|
||||
=
|
||||
pci_resource_start(devpriv->pci_dev,
|
||||
pcidio_boards[index].dioregs_badrindex);
|
||||
=
|
||||
pci_resource_start(devpriv->pci_dev,
|
||||
pcidio_boards[index].dioregs_badrindex);
|
||||
|
||||
/*
|
||||
* Allocate the subdevice structures. alloc_subdevice() is a
|
||||
@@ -257,9 +257,9 @@ static int pcidio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
|
||||
for (i = 0; i < thisboard->n_8255; i++) {
|
||||
subdev_8255_init(dev, dev->subdevices + i,
|
||||
NULL, devpriv->dio_reg_base + i * 4);
|
||||
NULL, devpriv->dio_reg_base + i * 4);
|
||||
printk(" subdev %d: base = 0x%lx\n", i,
|
||||
devpriv->dio_reg_base + i * 4);
|
||||
devpriv->dio_reg_base + i * 4);
|
||||
}
|
||||
|
||||
printk("attached\n");
|
||||
|
||||
@@ -103,29 +103,31 @@ struct cb_pcimdas_board {
|
||||
|
||||
static const struct cb_pcimdas_board cb_pcimdas_boards[] = {
|
||||
{
|
||||
.name = "PCIM-DAS1602/16",
|
||||
.device_id = 0x56,
|
||||
.ai_se_chans = 16,
|
||||
.ai_diff_chans = 8,
|
||||
.ai_bits = 16,
|
||||
.ai_speed = 10000, /* ?? */
|
||||
.ao_nchan = 2,
|
||||
.ao_bits = 12,
|
||||
.has_ao_fifo = 0, /* ?? */
|
||||
.ao_scan_speed = 10000,
|
||||
/* ?? */
|
||||
.fifo_size = 1024,
|
||||
.dio_bits = 24,
|
||||
.has_dio = 1,
|
||||
.name = "PCIM-DAS1602/16",
|
||||
.device_id = 0x56,
|
||||
.ai_se_chans = 16,
|
||||
.ai_diff_chans = 8,
|
||||
.ai_bits = 16,
|
||||
.ai_speed = 10000, /* ?? */
|
||||
.ao_nchan = 2,
|
||||
.ao_bits = 12,
|
||||
.has_ao_fifo = 0, /* ?? */
|
||||
.ao_scan_speed = 10000,
|
||||
/* ?? */
|
||||
.fifo_size = 1024,
|
||||
.dio_bits = 24,
|
||||
.has_dio = 1,
|
||||
/* .ranges = &cb_pcimdas_ranges, */
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/* This is used by modprobe to translate PCI IDs to drivers. Should
|
||||
* only be used for PCI and ISA-PnP devices */
|
||||
static DEFINE_PCI_DEVICE_TABLE(cb_pcimdas_pci_table) = {
|
||||
{PCI_VENDOR_ID_COMPUTERBOARDS, 0x0056, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{0}
|
||||
{
|
||||
PCI_VENDOR_ID_COMPUTERBOARDS, 0x0056, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{
|
||||
0}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, cb_pcimdas_pci_table);
|
||||
@@ -176,7 +178,8 @@ struct cb_pcimdas_private {
|
||||
* the board, and also about the kernel module that contains
|
||||
* the device code.
|
||||
*/
|
||||
static int cb_pcimdas_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int cb_pcimdas_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int cb_pcimdas_detach(struct comedi_device *dev);
|
||||
static struct comedi_driver driver_cb_pcimdas = {
|
||||
.driver_name = "cb_pcimdas",
|
||||
@@ -185,12 +188,15 @@ static struct comedi_driver driver_cb_pcimdas = {
|
||||
.detach = cb_pcimdas_detach,
|
||||
};
|
||||
|
||||
static int cb_pcimdas_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int cb_pcimdas_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int cb_pcimdas_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int cb_pcimdas_ai_rinsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int cb_pcimdas_ao_winsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int cb_pcimdas_ao_rinsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
/*
|
||||
* Attach is called by the Comedi core to configure the driver
|
||||
@@ -198,7 +204,8 @@ static int cb_pcimdas_ao_rinsn(struct comedi_device *dev, struct comedi_subdevic
|
||||
* in the driver structure, dev->board_ptr contains that
|
||||
* address.
|
||||
*/
|
||||
static int cb_pcimdas_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
static int cb_pcimdas_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it)
|
||||
{
|
||||
struct comedi_subdevice *s;
|
||||
struct pci_dev *pcidev;
|
||||
@@ -219,22 +226,21 @@ static int cb_pcimdas_attach(struct comedi_device *dev, struct comedi_devconfig
|
||||
printk("\n");
|
||||
|
||||
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)) {
|
||||
pcidev != NULL;
|
||||
pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
|
||||
/* is it not a computer boards card? */
|
||||
if (pcidev->vendor != PCI_VENDOR_ID_COMPUTERBOARDS)
|
||||
continue;
|
||||
/* loop through cards supported by this driver */
|
||||
for (index = 0; index < N_BOARDS; index++) {
|
||||
if (cb_pcimdas_boards[index].device_id !=
|
||||
pcidev->device)
|
||||
pcidev->device)
|
||||
continue;
|
||||
/* was a particular bus/slot requested? */
|
||||
if (it->options[0] || it->options[1]) {
|
||||
/* are we on the wrong bus/slot? */
|
||||
if (pcidev->bus->number != it->options[0] ||
|
||||
PCI_SLOT(pcidev->devfn) !=
|
||||
it->options[1]) {
|
||||
PCI_SLOT(pcidev->devfn) != it->options[1]) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -245,13 +251,13 @@ static int cb_pcimdas_attach(struct comedi_device *dev, struct comedi_devconfig
|
||||
}
|
||||
|
||||
printk("No supported ComputerBoards/MeasurementComputing card found on "
|
||||
"requested position\n");
|
||||
"requested position\n");
|
||||
return -EIO;
|
||||
|
||||
found:
|
||||
found:
|
||||
|
||||
printk("Found %s on bus %i, slot %i\n", cb_pcimdas_boards[index].name,
|
||||
pcidev->bus->number, PCI_SLOT(pcidev->devfn));
|
||||
pcidev->bus->number, PCI_SLOT(pcidev->devfn));
|
||||
|
||||
/* Warn about non-tested features */
|
||||
switch (thisboard->device_id) {
|
||||
@@ -259,7 +265,7 @@ static int cb_pcimdas_attach(struct comedi_device *dev, struct comedi_devconfig
|
||||
break;
|
||||
default:
|
||||
printk("THIS CARD IS UNSUPPORTED.\n"
|
||||
"PLEASE REPORT USAGE TO <mocelet@sucs.org>\n");
|
||||
"PLEASE REPORT USAGE TO <mocelet@sucs.org>\n");
|
||||
};
|
||||
|
||||
if (comedi_pci_enable(pcidev, "cb_pcimdas")) {
|
||||
@@ -373,8 +379,9 @@ static int cb_pcimdas_detach(struct comedi_device *dev)
|
||||
* "instructions" read/write data in "one-shot" or "software-triggered"
|
||||
* mode.
|
||||
*/
|
||||
static int cb_pcimdas_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int cb_pcimdas_ai_rinsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int n, i;
|
||||
unsigned int d;
|
||||
@@ -438,8 +445,9 @@ static int cb_pcimdas_ai_rinsn(struct comedi_device *dev, struct comedi_subdevic
|
||||
return n;
|
||||
}
|
||||
|
||||
static int cb_pcimdas_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int cb_pcimdas_ao_winsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int i;
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
@@ -466,8 +474,9 @@ static int cb_pcimdas_ao_winsn(struct comedi_device *dev, struct comedi_subdevic
|
||||
|
||||
/* AO subdevices should have a read insn as well as a write insn.
|
||||
* Usually this means copying a value stored in devpriv. */
|
||||
static int cb_pcimdas_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int cb_pcimdas_ao_rinsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int i;
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
|
||||
@@ -118,16 +118,16 @@ enum DIO_METHODS {
|
||||
|
||||
static const struct board_struct boards[] = {
|
||||
{
|
||||
.name = "cb_pcimdda06-16",
|
||||
.device_id = PCI_ID_PCIM_DDA06_16,
|
||||
.ao_chans = 6,
|
||||
.ao_bits = 16,
|
||||
.dio_chans = 24,
|
||||
.dio_method = DIO_8255,
|
||||
.dio_offset = 12,
|
||||
.regs_badrindex = 3,
|
||||
.reg_sz = 16,
|
||||
}
|
||||
.name = "cb_pcimdda06-16",
|
||||
.device_id = PCI_ID_PCIM_DDA06_16,
|
||||
.ao_chans = 6,
|
||||
.ao_bits = 16,
|
||||
.dio_chans = 24,
|
||||
.dio_method = DIO_8255,
|
||||
.dio_offset = 12,
|
||||
.regs_badrindex = 3,
|
||||
.reg_sz = 16,
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -143,9 +143,10 @@ static const struct board_struct boards[] = {
|
||||
/* Please add your PCI vendor ID to comedidev.h, and it will be forwarded
|
||||
* upstream. */
|
||||
static DEFINE_PCI_DEVICE_TABLE(pci_table) = {
|
||||
{PCI_VENDOR_ID_COMPUTERBOARDS, PCI_ID_PCIM_DDA06_16, PCI_ANY_ID,
|
||||
PCI_ANY_ID, 0, 0, 0},
|
||||
{0}
|
||||
{
|
||||
PCI_VENDOR_ID_COMPUTERBOARDS, PCI_ID_PCIM_DDA06_16, PCI_ANY_ID,
|
||||
PCI_ANY_ID, 0, 0, 0}, {
|
||||
0}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, pci_table);
|
||||
@@ -190,15 +191,15 @@ static struct comedi_driver cb_pcimdda_driver = {
|
||||
|
||||
MODULE_AUTHOR("Calin A. Culianu <calin@rtlab.org>");
|
||||
MODULE_DESCRIPTION("Comedi low-level driver for the Computerboards PCIM-DDA "
|
||||
"series. Currently only supports PCIM-DDA06-16 (which "
|
||||
"also happens to be the only board in this series. :) ) ");
|
||||
"series. Currently only supports PCIM-DDA06-16 (which "
|
||||
"also happens to be the only board in this series. :) ) ");
|
||||
MODULE_LICENSE("GPL");
|
||||
COMEDI_PCI_INITCLEANUP_NOMODULE(cb_pcimdda_driver, pci_table);
|
||||
|
||||
static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
HELPER FUNCTION DECLARATIONS
|
||||
@@ -207,7 +208,7 @@ static int ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
/* returns a maxdata value for a given n_bits */
|
||||
static inline unsigned int figure_out_maxdata(int bits)
|
||||
{
|
||||
return ((unsigned int) 1 << bits) - 1;
|
||||
return ((unsigned int)1 << bits) - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -344,7 +345,7 @@ static int detach(struct comedi_device *dev)
|
||||
|
||||
if (devpriv->attached_successfully && thisboard)
|
||||
printk("comedi%d: %s: detached\n", dev->minor,
|
||||
thisboard->name);
|
||||
thisboard->name);
|
||||
|
||||
}
|
||||
|
||||
@@ -352,7 +353,7 @@ static int detach(struct comedi_device *dev)
|
||||
}
|
||||
|
||||
static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int i;
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
@@ -391,7 +392,7 @@ static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
applications, I would imagine.
|
||||
*/
|
||||
static int ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int i;
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
@@ -431,8 +432,8 @@ static int probe(struct comedi_device *dev, const struct comedi_devconfig *it)
|
||||
unsigned long registers;
|
||||
|
||||
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)) {
|
||||
pcidev != NULL;
|
||||
pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
|
||||
/* is it not a computer boards card? */
|
||||
if (pcidev->vendor != PCI_VENDOR_ID_COMPUTERBOARDS)
|
||||
continue;
|
||||
@@ -444,8 +445,7 @@ static int probe(struct comedi_device *dev, const struct comedi_devconfig *it)
|
||||
if (it->options[0] || it->options[1]) {
|
||||
/* are we on the wrong bus/slot? */
|
||||
if (pcidev->bus->number != it->options[0] ||
|
||||
PCI_SLOT(pcidev->devfn) !=
|
||||
it->options[1]) {
|
||||
PCI_SLOT(pcidev->devfn) != it->options[1]) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -454,20 +454,21 @@ static int probe(struct comedi_device *dev, const struct comedi_devconfig *it)
|
||||
devpriv->pci_dev = pcidev;
|
||||
dev->board_ptr = boards + index;
|
||||
if (comedi_pci_enable(pcidev, thisboard->name)) {
|
||||
printk("cb_pcimdda: Failed to enable PCI device and request regions\n");
|
||||
printk
|
||||
("cb_pcimdda: Failed to enable PCI device and request regions\n");
|
||||
return -EIO;
|
||||
}
|
||||
registers =
|
||||
pci_resource_start(devpriv->pci_dev,
|
||||
REGS_BADRINDEX);
|
||||
pci_resource_start(devpriv->pci_dev,
|
||||
REGS_BADRINDEX);
|
||||
devpriv->registers = registers;
|
||||
devpriv->dio_registers
|
||||
= devpriv->registers + thisboard->dio_offset;
|
||||
= devpriv->registers + thisboard->dio_offset;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
printk("cb_pcimdda: No supported ComputerBoards/MeasurementComputing "
|
||||
"card found at the requested position\n");
|
||||
"card found at the requested position\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
@@ -132,8 +132,8 @@ struct BondingBoard {
|
||||
|
||||
static const struct BondingBoard bondingBoards[] = {
|
||||
{
|
||||
.name = MODULE_NAME,
|
||||
},
|
||||
.name = MODULE_NAME,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -176,7 +176,8 @@ struct Private {
|
||||
* the board, and also about the kernel module that contains
|
||||
* the device code.
|
||||
*/
|
||||
static int bonding_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int bonding_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int bonding_detach(struct comedi_device *dev);
|
||||
/** Build Private array of all devices.. */
|
||||
static int doDevConfig(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
@@ -186,10 +187,10 @@ static void doDevUnconfig(struct comedi_device *dev);
|
||||
static void *Realloc(const void *ptr, size_t len, size_t old_len);
|
||||
|
||||
static struct comedi_driver driver_bonding = {
|
||||
.driver_name = MODULE_NAME,
|
||||
.module = THIS_MODULE,
|
||||
.attach = bonding_attach,
|
||||
.detach = bonding_detach,
|
||||
.driver_name = MODULE_NAME,
|
||||
.module = THIS_MODULE,
|
||||
.attach = bonding_attach,
|
||||
.detach = bonding_detach,
|
||||
/* It is not necessary to implement the following members if you are
|
||||
* writing a driver for a ISA PnP or PCI card */
|
||||
/* Most drivers will support multiple types of boards by
|
||||
@@ -208,15 +209,18 @@ static struct comedi_driver driver_bonding = {
|
||||
* the type of board in software. ISA PnP, PCI, and PCMCIA
|
||||
* devices are such boards.
|
||||
*/
|
||||
.board_name = &bondingBoards[0].name,
|
||||
.offset = sizeof(struct BondingBoard),
|
||||
.num_names = ARRAY_SIZE(bondingBoards),
|
||||
.board_name = &bondingBoards[0].name,
|
||||
.offset = sizeof(struct BondingBoard),
|
||||
.num_names = ARRAY_SIZE(bondingBoards),
|
||||
};
|
||||
|
||||
static int bonding_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
static int bonding_dio_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int bonding_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int bonding_dio_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
|
||||
/*
|
||||
* Attach is called by the Comedi core to configure the driver
|
||||
@@ -224,7 +228,8 @@ static int bonding_dio_insn_config(struct comedi_device *dev, struct comedi_subd
|
||||
* in the driver structure, dev->board_ptr contains that
|
||||
* address.
|
||||
*/
|
||||
static int bonding_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
static int bonding_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it)
|
||||
{
|
||||
struct comedi_subdevice *s;
|
||||
|
||||
@@ -293,7 +298,8 @@ static int bonding_detach(struct comedi_device *dev)
|
||||
* useful to applications if you implement the insn_bits interface.
|
||||
* This allows packed reading/writing of the DIO channels. The
|
||||
* comedi core can convert between insn_bits and insn_read/write */
|
||||
static int bonding_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
static int bonding_dio_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
#define LSAMPL_BITS (sizeof(unsigned int)*8)
|
||||
@@ -317,14 +323,14 @@ static int bonding_dio_insn_bits(struct comedi_device *dev, struct comedi_subdev
|
||||
|
||||
/* Argh, we have >= LSAMPL_BITS chans.. take all bits */
|
||||
if (bdev->nchans >= LSAMPL_BITS)
|
||||
subdevMask = (unsigned int) (-1);
|
||||
subdevMask = (unsigned int)(-1);
|
||||
|
||||
writeMask = (data[0] >> num_done) & subdevMask;
|
||||
dataBits = (data[1] >> num_done) & subdevMask;
|
||||
|
||||
/* Read/Write the new digital lines */
|
||||
if (comedi_dio_bitfield(bdev->dev, bdev->subdev, writeMask,
|
||||
&dataBits) != 2)
|
||||
&dataBits) != 2)
|
||||
return -EINVAL;
|
||||
|
||||
/* Make room for the new bits in data[1], the return value */
|
||||
@@ -340,7 +346,8 @@ static int bonding_dio_insn_bits(struct comedi_device *dev, struct comedi_subdev
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
static int bonding_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
static int bonding_dio_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int chan = CR_CHAN(insn->chanspec), ret, io_bits = s->io_bits;
|
||||
@@ -366,7 +373,7 @@ static int bonding_dio_insn_config(struct comedi_device *dev, struct comedi_subd
|
||||
break;
|
||||
case INSN_CONFIG_DIO_QUERY:
|
||||
data[1] =
|
||||
(io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
|
||||
(io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
|
||||
return insn->n;
|
||||
break;
|
||||
default:
|
||||
@@ -435,7 +442,7 @@ static int doDevConfig(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
|
||||
/* Do DIO, as that's all we support now.. */
|
||||
while ((sdev = comedi_find_subdevice_by_type(d, COMEDI_SUBD_DIO,
|
||||
sdev + 1)) > -1) {
|
||||
sdev + 1)) > -1) {
|
||||
nchans = comedi_get_n_channels(d, sdev);
|
||||
if (nchans <= 0) {
|
||||
ERROR("comedi_get_n_channels() returned %d "
|
||||
@@ -465,8 +472,8 @@ static int doDevConfig(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
/* ergh.. ugly.. we need to realloc :( */
|
||||
tmp = devpriv->ndevs * sizeof(bdev);
|
||||
devpriv->devs =
|
||||
Realloc(devpriv->devs,
|
||||
++devpriv->ndevs * sizeof(bdev), tmp);
|
||||
Realloc(devpriv->devs,
|
||||
++devpriv->ndevs * sizeof(bdev), tmp);
|
||||
if (!devpriv->devs) {
|
||||
ERROR("Could not allocate memory. "
|
||||
"Out of memory?");
|
||||
@@ -478,10 +485,9 @@ static int doDevConfig(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
/** Append dev:subdev to devpriv->name */
|
||||
char buf[20];
|
||||
int left =
|
||||
MAX_BOARD_NAME - strlen(devpriv->name) -
|
||||
1;
|
||||
MAX_BOARD_NAME - strlen(devpriv->name) - 1;
|
||||
snprintf(buf, sizeof(buf), "%d:%d ", dev->minor,
|
||||
bdev->subdev);
|
||||
bdev->subdev);
|
||||
buf[sizeof(buf) - 1] = 0;
|
||||
strncat(devpriv->name, buf, left);
|
||||
}
|
||||
|
||||
@@ -42,8 +42,8 @@ static void increment_scan_progress(struct comedi_subdevice *subd,
|
||||
}
|
||||
|
||||
/* Writes an array of data points to comedi's buffer */
|
||||
unsigned int cfc_write_array_to_buffer(struct comedi_subdevice *subd, void *data,
|
||||
unsigned int num_bytes)
|
||||
unsigned int cfc_write_array_to_buffer(struct comedi_subdevice *subd,
|
||||
void *data, unsigned int num_bytes)
|
||||
{
|
||||
struct comedi_async *async = subd->async;
|
||||
unsigned int retval;
|
||||
@@ -65,10 +65,11 @@ unsigned int cfc_write_array_to_buffer(struct comedi_subdevice *subd, void *data
|
||||
|
||||
return num_bytes;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(cfc_write_array_to_buffer);
|
||||
|
||||
unsigned int cfc_read_array_from_buffer(struct comedi_subdevice *subd, void *data,
|
||||
unsigned int num_bytes)
|
||||
unsigned int cfc_read_array_from_buffer(struct comedi_subdevice *subd,
|
||||
void *data, unsigned int num_bytes)
|
||||
{
|
||||
struct comedi_async *async = subd->async;
|
||||
|
||||
@@ -83,9 +84,11 @@ unsigned int cfc_read_array_from_buffer(struct comedi_subdevice *subd, void *dat
|
||||
|
||||
return num_bytes;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(cfc_read_array_from_buffer);
|
||||
|
||||
unsigned int cfc_handle_events(struct comedi_device *dev, struct comedi_subdevice *subd)
|
||||
unsigned int cfc_handle_events(struct comedi_device *dev,
|
||||
struct comedi_subdevice *subd)
|
||||
{
|
||||
unsigned int events = subd->async->events;
|
||||
|
||||
@@ -99,6 +102,7 @@ unsigned int cfc_handle_events(struct comedi_device *dev, struct comedi_subdevic
|
||||
|
||||
return events;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(cfc_handle_events);
|
||||
|
||||
MODULE_AUTHOR("Frank Mori Hess <fmhess@users.sourceforge.net>");
|
||||
|
||||
@@ -40,8 +40,8 @@ static inline unsigned int cfc_write_to_buffer(struct comedi_subdevice *subd,
|
||||
return cfc_write_array_to_buffer(subd, &data, sizeof(data));
|
||||
};
|
||||
|
||||
static inline unsigned int cfc_write_long_to_buffer(struct comedi_subdevice *subd,
|
||||
unsigned int data)
|
||||
static inline unsigned int cfc_write_long_to_buffer(struct comedi_subdevice
|
||||
*subd, unsigned int data)
|
||||
{
|
||||
return cfc_write_array_to_buffer(subd, &data, sizeof(data));
|
||||
};
|
||||
|
||||
@@ -91,13 +91,14 @@ pin, which can be used to wake up tasks.
|
||||
#define PARPORT_B 1
|
||||
#define PARPORT_C 2
|
||||
|
||||
static int parport_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int parport_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int parport_detach(struct comedi_device *dev);
|
||||
static struct comedi_driver driver_parport = {
|
||||
.driver_name = "comedi_parport",
|
||||
.module = THIS_MODULE,
|
||||
.attach = parport_attach,
|
||||
.detach = parport_detach,
|
||||
.driver_name = "comedi_parport",
|
||||
.module = THIS_MODULE,
|
||||
.attach = parport_attach,
|
||||
.detach = parport_detach,
|
||||
};
|
||||
|
||||
COMEDI_INITCLEANUP(driver_parport);
|
||||
@@ -124,7 +125,8 @@ static int parport_insn_a(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int parport_insn_config_a(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
static int parport_insn_config_a(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
if (data[0]) {
|
||||
@@ -168,7 +170,8 @@ static int parport_insn_c(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int parport_intr_insn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
static int parport_intr_insn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
if (insn->n < 1)
|
||||
@@ -178,7 +181,8 @@ static int parport_intr_insn(struct comedi_device *dev, struct comedi_subdevice
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int parport_intr_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
static int parport_intr_cmdtest(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd)
|
||||
{
|
||||
int err = 0;
|
||||
@@ -253,7 +257,8 @@ static int parport_intr_cmdtest(struct comedi_device *dev, struct comedi_subdevi
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parport_intr_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
static int parport_intr_cmd(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
devpriv->c_data |= 0x10;
|
||||
outb(devpriv->c_data, dev->iobase + PARPORT_C);
|
||||
@@ -263,7 +268,8 @@ static int parport_intr_cmd(struct comedi_device *dev, struct comedi_subdevice *
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parport_intr_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
static int parport_intr_cancel(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
printk(KERN_DEBUG "parport_intr_cancel()\n");
|
||||
|
||||
@@ -292,7 +298,8 @@ static irqreturn_t parport_interrupt(int irq, void *d)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int parport_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
static int parport_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it)
|
||||
{
|
||||
int ret;
|
||||
unsigned int irq;
|
||||
|
||||
@@ -69,11 +69,11 @@ struct waveform_board {
|
||||
|
||||
static const struct waveform_board waveform_boards[] = {
|
||||
{
|
||||
.name = "comedi_test",
|
||||
.ai_chans = N_CHANS,
|
||||
.ai_bits = 16,
|
||||
.have_dio = 0,
|
||||
},
|
||||
.name = "comedi_test",
|
||||
.ai_chans = N_CHANS,
|
||||
.ai_bits = 16,
|
||||
.have_dio = 0,
|
||||
},
|
||||
};
|
||||
|
||||
#define thisboard ((const struct waveform_board *)dev->board_ptr)
|
||||
@@ -84,7 +84,7 @@ struct waveform_private {
|
||||
struct timeval last; /* time at which last timer interrupt occured */
|
||||
unsigned int uvolt_amplitude; /* waveform amplitude in microvolts */
|
||||
unsigned long usec_period; /* waveform period in microseconds */
|
||||
unsigned long usec_current; /* current time (modulo waveform period) */
|
||||
unsigned long usec_current; /* current time (modulo waveform period) */
|
||||
unsigned long usec_remainder; /* usec since last scan; */
|
||||
unsigned long ai_count; /* number of conversions remaining */
|
||||
unsigned int scan_period; /* scan period in usec */
|
||||
@@ -94,36 +94,42 @@ struct waveform_private {
|
||||
};
|
||||
#define devpriv ((struct waveform_private *)dev->private)
|
||||
|
||||
static int waveform_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int waveform_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int waveform_detach(struct comedi_device *dev);
|
||||
static struct comedi_driver driver_waveform = {
|
||||
.driver_name = "comedi_test",
|
||||
.module = THIS_MODULE,
|
||||
.attach = waveform_attach,
|
||||
.detach = waveform_detach,
|
||||
.board_name = &waveform_boards[0].name,
|
||||
.offset = sizeof(struct waveform_board),
|
||||
.num_names = ARRAY_SIZE(waveform_boards),
|
||||
.driver_name = "comedi_test",
|
||||
.module = THIS_MODULE,
|
||||
.attach = waveform_attach,
|
||||
.detach = waveform_detach,
|
||||
.board_name = &waveform_boards[0].name,
|
||||
.offset = sizeof(struct waveform_board),
|
||||
.num_names = ARRAY_SIZE(waveform_boards),
|
||||
};
|
||||
|
||||
COMEDI_INITCLEANUP(driver_waveform);
|
||||
|
||||
static int waveform_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
static int waveform_ai_cmdtest(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd);
|
||||
static int waveform_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
|
||||
static int waveform_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
|
||||
static int waveform_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
static int waveform_ai_cmd(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s);
|
||||
static int waveform_ai_cancel(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s);
|
||||
static int waveform_ai_insn_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int waveform_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
static int waveform_ao_insn_write(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static short fake_sawtooth(struct comedi_device *dev, unsigned int range,
|
||||
unsigned long current_time);
|
||||
unsigned long current_time);
|
||||
static short fake_squarewave(struct comedi_device *dev, unsigned int range,
|
||||
unsigned long current_time);
|
||||
static short fake_flatline(struct comedi_device *dev, unsigned int range,
|
||||
unsigned long current_time);
|
||||
static short fake_flatline(struct comedi_device *dev, unsigned int range,
|
||||
unsigned long current_time);
|
||||
static short fake_waveform(struct comedi_device *dev, unsigned int channel,
|
||||
unsigned int range, unsigned long current_time);
|
||||
unsigned int range, unsigned long current_time);
|
||||
|
||||
/* 1000 nanosec in a microsec */
|
||||
static const int nano_per_micro = 1000;
|
||||
@@ -132,9 +138,9 @@ static const int nano_per_micro = 1000;
|
||||
static const struct comedi_lrange waveform_ai_ranges = {
|
||||
2,
|
||||
{
|
||||
BIP_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
}
|
||||
BIP_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -144,7 +150,7 @@ static const struct comedi_lrange waveform_ai_ranges = {
|
||||
*/
|
||||
static void waveform_ai_interrupt(unsigned long arg)
|
||||
{
|
||||
struct comedi_device *dev = (struct comedi_device *) arg;
|
||||
struct comedi_device *dev = (struct comedi_device *)arg;
|
||||
struct comedi_async *async = dev->read_subdev->async;
|
||||
struct comedi_cmd *cmd = &async->cmd;
|
||||
unsigned int i, j;
|
||||
@@ -156,27 +162,34 @@ static void waveform_ai_interrupt(unsigned long arg)
|
||||
do_gettimeofday(&now);
|
||||
|
||||
elapsed_time =
|
||||
1000000 * (now.tv_sec - devpriv->last.tv_sec) + now.tv_usec -
|
||||
devpriv->last.tv_usec;
|
||||
1000000 * (now.tv_sec - devpriv->last.tv_sec) + now.tv_usec -
|
||||
devpriv->last.tv_usec;
|
||||
devpriv->last = now;
|
||||
num_scans =
|
||||
(devpriv->usec_remainder + elapsed_time) / devpriv->scan_period;
|
||||
(devpriv->usec_remainder + elapsed_time) / devpriv->scan_period;
|
||||
devpriv->usec_remainder =
|
||||
(devpriv->usec_remainder + elapsed_time) % devpriv->scan_period;
|
||||
(devpriv->usec_remainder + elapsed_time) % devpriv->scan_period;
|
||||
async->events = 0;
|
||||
|
||||
for (i = 0; i < num_scans; i++) {
|
||||
for (j = 0; j < cmd->chanlist_len; j++) {
|
||||
cfc_write_to_buffer(dev->read_subdev,
|
||||
fake_waveform(dev, CR_CHAN(cmd->chanlist[j]),
|
||||
CR_RANGE(cmd->chanlist[j]),
|
||||
devpriv->usec_current +
|
||||
i * devpriv->scan_period +
|
||||
j * devpriv->convert_period));
|
||||
fake_waveform(dev,
|
||||
CR_CHAN(cmd->
|
||||
chanlist[j]),
|
||||
CR_RANGE(cmd->
|
||||
chanlist[j]),
|
||||
devpriv->
|
||||
usec_current +
|
||||
i *
|
||||
devpriv->scan_period +
|
||||
j *
|
||||
devpriv->
|
||||
convert_period));
|
||||
}
|
||||
devpriv->ai_count++;
|
||||
if (cmd->stop_src == TRIG_COUNT
|
||||
&& devpriv->ai_count >= cmd->stop_arg) {
|
||||
&& devpriv->ai_count >= cmd->stop_arg) {
|
||||
async->events |= COMEDI_CB_EOA;
|
||||
break;
|
||||
}
|
||||
@@ -193,7 +206,8 @@ static void waveform_ai_interrupt(unsigned long arg)
|
||||
comedi_event(dev, dev->read_subdev);
|
||||
}
|
||||
|
||||
static int waveform_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
static int waveform_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it)
|
||||
{
|
||||
struct comedi_subdevice *s;
|
||||
int amplitude = it->options[0];
|
||||
@@ -255,8 +269,8 @@ static int waveform_attach(struct comedi_device *dev, struct comedi_devconfig *i
|
||||
devpriv->timer.data = (unsigned long)dev;
|
||||
|
||||
printk(KERN_INFO "comedi%d: comedi_test: "
|
||||
"%i microvolt, %li microsecond waveform attached\n", dev->minor,
|
||||
devpriv->uvolt_amplitude, devpriv->usec_period);
|
||||
"%i microvolt, %li microsecond waveform attached\n", dev->minor,
|
||||
devpriv->uvolt_amplitude, devpriv->usec_period);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -270,7 +284,8 @@ static int waveform_detach(struct comedi_device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int waveform_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
static int waveform_ai_cmdtest(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd)
|
||||
{
|
||||
int err = 0;
|
||||
@@ -336,10 +351,10 @@ static int waveform_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevic
|
||||
err++;
|
||||
}
|
||||
if (cmd->convert_src == TRIG_TIMER &&
|
||||
cmd->scan_begin_arg <
|
||||
cmd->convert_arg * cmd->chanlist_len) {
|
||||
cmd->scan_begin_arg <
|
||||
cmd->convert_arg * cmd->chanlist_len) {
|
||||
cmd->scan_begin_arg =
|
||||
cmd->convert_arg * cmd->chanlist_len;
|
||||
cmd->convert_arg * cmd->chanlist_len;
|
||||
err++;
|
||||
}
|
||||
}
|
||||
@@ -377,8 +392,8 @@ static int waveform_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevic
|
||||
tmp = cmd->scan_begin_arg;
|
||||
/* round to nearest microsec */
|
||||
cmd->scan_begin_arg =
|
||||
nano_per_micro * ((tmp +
|
||||
(nano_per_micro / 2)) / nano_per_micro);
|
||||
nano_per_micro * ((tmp +
|
||||
(nano_per_micro / 2)) / nano_per_micro);
|
||||
if (tmp != cmd->scan_begin_arg)
|
||||
err++;
|
||||
}
|
||||
@@ -386,8 +401,8 @@ static int waveform_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevic
|
||||
tmp = cmd->convert_arg;
|
||||
/* round to nearest microsec */
|
||||
cmd->convert_arg =
|
||||
nano_per_micro * ((tmp +
|
||||
(nano_per_micro / 2)) / nano_per_micro);
|
||||
nano_per_micro * ((tmp +
|
||||
(nano_per_micro / 2)) / nano_per_micro);
|
||||
if (tmp != cmd->convert_arg)
|
||||
err++;
|
||||
}
|
||||
@@ -398,13 +413,14 @@ static int waveform_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevic
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int waveform_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
static int waveform_ai_cmd(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
struct comedi_cmd *cmd = &s->async->cmd;
|
||||
|
||||
if (cmd->flags & TRIG_RT) {
|
||||
comedi_error(dev,
|
||||
"commands at RT priority not supported in this driver");
|
||||
"commands at RT priority not supported in this driver");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -430,7 +446,8 @@ static int waveform_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int waveform_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
static int waveform_ai_cancel(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
devpriv->timer_running = 0;
|
||||
del_timer(&devpriv->timer);
|
||||
@@ -438,12 +455,13 @@ static int waveform_ai_cancel(struct comedi_device *dev, struct comedi_subdevice
|
||||
}
|
||||
|
||||
static short fake_sawtooth(struct comedi_device *dev, unsigned int range_index,
|
||||
unsigned long current_time)
|
||||
unsigned long current_time)
|
||||
{
|
||||
struct comedi_subdevice *s = dev->read_subdev;
|
||||
unsigned int offset = s->maxdata / 2;
|
||||
u64 value;
|
||||
const struct comedi_krange *krange = &s->range_table->range[range_index];
|
||||
const struct comedi_krange *krange =
|
||||
&s->range_table->range[range_index];
|
||||
u64 binary_amplitude;
|
||||
|
||||
binary_amplitude = s->maxdata;
|
||||
@@ -458,13 +476,16 @@ static short fake_sawtooth(struct comedi_device *dev, unsigned int range_index,
|
||||
|
||||
return offset + value;
|
||||
}
|
||||
static short fake_squarewave(struct comedi_device *dev, unsigned int range_index,
|
||||
unsigned long current_time)
|
||||
|
||||
static short fake_squarewave(struct comedi_device *dev,
|
||||
unsigned int range_index,
|
||||
unsigned long current_time)
|
||||
{
|
||||
struct comedi_subdevice *s = dev->read_subdev;
|
||||
unsigned int offset = s->maxdata / 2;
|
||||
u64 value;
|
||||
const struct comedi_krange *krange = &s->range_table->range[range_index];
|
||||
const struct comedi_krange *krange =
|
||||
&s->range_table->range[range_index];
|
||||
current_time %= devpriv->usec_period;
|
||||
|
||||
value = s->maxdata;
|
||||
@@ -478,14 +499,14 @@ static short fake_squarewave(struct comedi_device *dev, unsigned int range_index
|
||||
}
|
||||
|
||||
static short fake_flatline(struct comedi_device *dev, unsigned int range_index,
|
||||
unsigned long current_time)
|
||||
unsigned long current_time)
|
||||
{
|
||||
return dev->read_subdev->maxdata / 2;
|
||||
}
|
||||
|
||||
/* generates a different waveform depending on what channel is read */
|
||||
static short fake_waveform(struct comedi_device *dev, unsigned int channel,
|
||||
unsigned int range, unsigned long current_time)
|
||||
unsigned int range, unsigned long current_time)
|
||||
{
|
||||
enum {
|
||||
SAWTOOTH_CHAN,
|
||||
@@ -505,7 +526,8 @@ static short fake_waveform(struct comedi_device *dev, unsigned int channel,
|
||||
return fake_flatline(dev, range, current_time);
|
||||
}
|
||||
|
||||
static int waveform_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
static int waveform_ai_insn_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int i, chan = CR_CHAN(insn->chanspec);
|
||||
@@ -516,7 +538,8 @@ static int waveform_ai_insn_read(struct comedi_device *dev, struct comedi_subdev
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
static int waveform_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
static int waveform_ao_insn_write(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int i, chan = CR_CHAN(insn->chanspec);
|
||||
|
||||
@@ -57,9 +57,10 @@ static const struct contec_board contec_boards[] = {
|
||||
|
||||
#define PCI_DEVICE_ID_PIO1616L 0x8172
|
||||
static DEFINE_PCI_DEVICE_TABLE(contec_pci_table) = {
|
||||
{PCI_VENDOR_ID_CONTEC, PCI_DEVICE_ID_PIO1616L, PCI_ANY_ID, PCI_ANY_ID,
|
||||
0, 0, PIO1616L},
|
||||
{0}
|
||||
{
|
||||
PCI_VENDOR_ID_CONTEC, PCI_DEVICE_ID_PIO1616L, PCI_ANY_ID,
|
||||
PCI_ANY_ID, 0, 0, PIO1616L}, {
|
||||
0}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, contec_pci_table);
|
||||
@@ -75,7 +76,8 @@ struct contec_private {
|
||||
|
||||
#define devpriv ((struct contec_private *)dev->private)
|
||||
|
||||
static int contec_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int contec_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int contec_detach(struct comedi_device *dev);
|
||||
static struct comedi_driver driver_contec = {
|
||||
.driver_name = "contec_pci_dio",
|
||||
@@ -85,14 +87,16 @@ static struct comedi_driver driver_contec = {
|
||||
};
|
||||
|
||||
/* Classic digital IO */
|
||||
static int contec_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int contec_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int contec_di_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int contec_do_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
#if 0
|
||||
static int contec_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd);
|
||||
struct comedi_cmd *cmd);
|
||||
|
||||
static int contec_ns_to_timer(unsigned int *ns, int round);
|
||||
#endif
|
||||
@@ -113,22 +117,22 @@ static int contec_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
return -ENOMEM;
|
||||
|
||||
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)) {
|
||||
pcidev != NULL;
|
||||
pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
|
||||
|
||||
if (pcidev->vendor == PCI_VENDOR_ID_CONTEC &&
|
||||
pcidev->device == PCI_DEVICE_ID_PIO1616L) {
|
||||
pcidev->device == PCI_DEVICE_ID_PIO1616L) {
|
||||
if (it->options[0] || it->options[1]) {
|
||||
/* Check bus and slot. */
|
||||
if (it->options[0] != pcidev->bus->number ||
|
||||
it->options[1] !=
|
||||
PCI_SLOT(pcidev->devfn)) {
|
||||
it->options[1] != PCI_SLOT(pcidev->devfn)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
devpriv->pci_dev = pcidev;
|
||||
if (comedi_pci_enable(pcidev, "contec_pci_dio")) {
|
||||
printk("error enabling PCI device and request regions!\n");
|
||||
printk
|
||||
("error enabling PCI device and request regions!\n");
|
||||
return -EIO;
|
||||
}
|
||||
dev->iobase = pci_resource_start(pcidev, 0);
|
||||
@@ -180,7 +184,7 @@ static int contec_detach(struct comedi_device *dev)
|
||||
|
||||
#if 0
|
||||
static int contec_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd)
|
||||
struct comedi_cmd *cmd)
|
||||
{
|
||||
printk("contec_cmdtest called\n");
|
||||
return 0;
|
||||
@@ -192,8 +196,9 @@ static int contec_ns_to_timer(unsigned int *ns, int round)
|
||||
}
|
||||
#endif
|
||||
|
||||
static int contec_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int contec_do_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
|
||||
printk("contec_do_insn_bits called\n");
|
||||
@@ -206,14 +211,15 @@ static int contec_do_insn_bits(struct comedi_device *dev, struct comedi_subdevic
|
||||
s->state &= ~data[0];
|
||||
s->state |= data[0] & data[1];
|
||||
printk(" out: %d on %lx\n", s->state,
|
||||
dev->iobase + thisboard->out_offs);
|
||||
dev->iobase + thisboard->out_offs);
|
||||
outw(s->state, dev->iobase + thisboard->out_offs);
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int contec_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int contec_di_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
|
||||
printk("contec_di_insn_bits called\n");
|
||||
|
||||
@@ -107,13 +107,10 @@ Configuration options:
|
||||
| +---------------- Unipolar
|
||||
+------------------------- Correction gain high
|
||||
|
||||
|
||||
|
||||
999. The card seems to have an incredible amount of capabilities, but
|
||||
trying to reverse engineer them from the Windows source is beyond my
|
||||
patience.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include "../comedidev.h"
|
||||
@@ -147,25 +144,32 @@ Configuration options:
|
||||
|
||||
/* Available ranges */
|
||||
static const struct comedi_lrange range_daqboard2000_ai = { 13, {
|
||||
RANGE(-10, 10),
|
||||
RANGE(-5, 5),
|
||||
RANGE(-2.5, 2.5),
|
||||
RANGE(-1.25, 1.25),
|
||||
RANGE(-0.625, 0.625),
|
||||
RANGE(-0.3125, 0.3125),
|
||||
RANGE(-0.156, 0.156),
|
||||
RANGE(0, 10),
|
||||
RANGE(0, 5),
|
||||
RANGE(0, 2.5),
|
||||
RANGE(0, 1.25),
|
||||
RANGE(0, 0.625),
|
||||
RANGE(0, 0.3125)
|
||||
}
|
||||
RANGE(-10, 10),
|
||||
RANGE(-5, 5),
|
||||
RANGE(-2.5,
|
||||
2.5),
|
||||
RANGE(-1.25,
|
||||
1.25),
|
||||
RANGE(-0.625,
|
||||
0.625),
|
||||
RANGE(-0.3125,
|
||||
0.3125),
|
||||
RANGE(-0.156,
|
||||
0.156),
|
||||
RANGE(0, 10),
|
||||
RANGE(0, 5),
|
||||
RANGE(0, 2.5),
|
||||
RANGE(0, 1.25),
|
||||
RANGE(0,
|
||||
0.625),
|
||||
RANGE(0,
|
||||
0.3125)
|
||||
}
|
||||
};
|
||||
|
||||
static const struct comedi_lrange range_daqboard2000_ao = { 1, {
|
||||
RANGE(-10, 10)
|
||||
}
|
||||
RANGE(-10, 10)
|
||||
}
|
||||
};
|
||||
|
||||
struct daqboard2000_hw {
|
||||
@@ -297,7 +301,8 @@ struct daqboard2000_hw {
|
||||
#define DAQBOARD2000_PosRefDacSelect 0x0100
|
||||
#define DAQBOARD2000_NegRefDacSelect 0x0000
|
||||
|
||||
static int daqboard2000_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int daqboard2000_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int daqboard2000_detach(struct comedi_device *dev);
|
||||
|
||||
static struct comedi_driver driver_daqboard2000 = {
|
||||
@@ -320,8 +325,9 @@ static const struct daq200_boardtype boardtypes[] = {
|
||||
#define this_board ((const struct daq200_boardtype *)dev->board_ptr)
|
||||
|
||||
static DEFINE_PCI_DEVICE_TABLE(daqboard2000_pci_table) = {
|
||||
{0x1616, 0x0409, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{0}
|
||||
{
|
||||
0x1616, 0x0409, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
0}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, daqboard2000_pci_table);
|
||||
@@ -394,17 +400,18 @@ static void setup_sampling(struct comedi_device *dev, int chan, int gain)
|
||||
writeAcqScanListEntry(dev, word3);
|
||||
}
|
||||
|
||||
static int daqboard2000_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int daqboard2000_ai_insn_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
int i;
|
||||
struct daqboard2000_hw *fpga = devpriv->daq;
|
||||
int gain, chan, timeout;
|
||||
|
||||
fpga->acqControl =
|
||||
DAQBOARD2000_AcqResetScanListFifo |
|
||||
DAQBOARD2000_AcqResetResultsFifo |
|
||||
DAQBOARD2000_AcqResetConfigPipe;
|
||||
DAQBOARD2000_AcqResetScanListFifo |
|
||||
DAQBOARD2000_AcqResetResultsFifo | DAQBOARD2000_AcqResetConfigPipe;
|
||||
|
||||
/* If pacer clock is not set to some high value (> 10 us), we
|
||||
risk multiple samples to be put into the result FIFO. */
|
||||
@@ -436,9 +443,8 @@ static int daqboard2000_ai_insn_read(struct comedi_device *dev, struct comedi_su
|
||||
/* udelay(2); */
|
||||
}
|
||||
for (timeout = 0; timeout < 20; timeout++) {
|
||||
if (fpga->
|
||||
acqControl &
|
||||
DAQBOARD2000_AcqResultsFIFOHasValidData) {
|
||||
if (fpga->acqControl &
|
||||
DAQBOARD2000_AcqResultsFIFOHasValidData) {
|
||||
break;
|
||||
}
|
||||
/* udelay(2); */
|
||||
@@ -451,8 +457,10 @@ static int daqboard2000_ai_insn_read(struct comedi_device *dev, struct comedi_su
|
||||
return i;
|
||||
}
|
||||
|
||||
static int daqboard2000_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int daqboard2000_ao_insn_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
int i;
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
@@ -464,8 +472,10 @@ static int daqboard2000_ao_insn_read(struct comedi_device *dev, struct comedi_su
|
||||
return i;
|
||||
}
|
||||
|
||||
static int daqboard2000_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int daqboard2000_ao_insn_write(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
int i;
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
@@ -521,7 +531,7 @@ static void daqboard2000_pulseProgPin(struct comedi_device *dev)
|
||||
writel(DAQBOARD2000_SECRProgPinHi, devpriv->plx + 0x6c);
|
||||
udelay(10000);
|
||||
writel(DAQBOARD2000_SECRProgPinLo, devpriv->plx + 0x6c);
|
||||
udelay(10000); /* Not in the original code, but I like symmetry... */
|
||||
udelay(10000); /* Not in the original code, but I like symmetry... */
|
||||
}
|
||||
|
||||
static int daqboard2000_pollCPLD(struct comedi_device *dev, int mask)
|
||||
@@ -550,14 +560,14 @@ static int daqboard2000_writeCPLD(struct comedi_device *dev, int data)
|
||||
udelay(10);
|
||||
writew(data, devpriv->daq + 0x1000);
|
||||
if ((readw(devpriv->daq + 0x1000) & DAQBOARD2000_CPLD_INIT) ==
|
||||
DAQBOARD2000_CPLD_INIT) {
|
||||
DAQBOARD2000_CPLD_INIT) {
|
||||
result = 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static int initialize_daqboard2000(struct comedi_device *dev,
|
||||
unsigned char *cpld_array, int len)
|
||||
unsigned char *cpld_array, int len)
|
||||
{
|
||||
int result = -EIO;
|
||||
/* Read the serial EEPROM control register */
|
||||
@@ -585,7 +595,7 @@ static int initialize_daqboard2000(struct comedi_device *dev,
|
||||
if (daqboard2000_pollCPLD(dev, DAQBOARD2000_CPLD_INIT)) {
|
||||
for (i = 0; i < len; i++) {
|
||||
if (cpld_array[i] == 0xff
|
||||
&& cpld_array[i + 1] == 0x20) {
|
||||
&& cpld_array[i + 1] == 0x20) {
|
||||
#ifdef DEBUG_EEPROM
|
||||
printk("Preamble found at %d\n", i);
|
||||
#endif
|
||||
@@ -594,8 +604,7 @@ static int initialize_daqboard2000(struct comedi_device *dev,
|
||||
}
|
||||
for (; i < len; i += 2) {
|
||||
int data =
|
||||
(cpld_array[i] << 8) + cpld_array[i +
|
||||
1];
|
||||
(cpld_array[i] << 8) + cpld_array[i + 1];
|
||||
if (!daqboard2000_writeCPLD(dev, data)) {
|
||||
break;
|
||||
}
|
||||
@@ -702,7 +711,7 @@ rmmod daqboard2000 ; rmmod comedi; make install ; modprobe daqboard2000; /usr/sb
|
||||
*/
|
||||
|
||||
static int daqboard2000_8255_cb(int dir, int port, int data,
|
||||
unsigned long ioaddr)
|
||||
unsigned long ioaddr)
|
||||
{
|
||||
int result = 0;
|
||||
if (dir) {
|
||||
@@ -718,7 +727,8 @@ static int daqboard2000_8255_cb(int dir, int port, int data,
|
||||
return result;
|
||||
}
|
||||
|
||||
static int daqboard2000_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
static int daqboard2000_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it)
|
||||
{
|
||||
int result = 0;
|
||||
struct comedi_subdevice *s;
|
||||
@@ -737,21 +747,20 @@ static int daqboard2000_attach(struct comedi_device *dev, struct comedi_devconfi
|
||||
return -ENOMEM;
|
||||
}
|
||||
for (card = pci_get_device(0x1616, 0x0409, NULL);
|
||||
card != NULL;
|
||||
card = pci_get_device(0x1616, 0x0409, card)) {
|
||||
card != NULL; card = pci_get_device(0x1616, 0x0409, card)) {
|
||||
if (bus || slot) {
|
||||
/* requested particular bus/slot */
|
||||
if (card->bus->number != bus ||
|
||||
PCI_SLOT(card->devfn) != slot) {
|
||||
PCI_SLOT(card->devfn) != slot) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break; /* found one */
|
||||
break; /* found one */
|
||||
}
|
||||
if (!card) {
|
||||
if (bus || slot)
|
||||
printk(" no daqboard2000 found at bus/slot: %d/%d\n",
|
||||
bus, slot);
|
||||
bus, slot);
|
||||
else
|
||||
printk(" no daqboard2000 found\n");
|
||||
return -EIO;
|
||||
@@ -759,8 +768,8 @@ static int daqboard2000_attach(struct comedi_device *dev, struct comedi_devconfi
|
||||
u32 id;
|
||||
int i;
|
||||
devpriv->pci_dev = card;
|
||||
id = ((u32) card->subsystem_device << 16) | card->
|
||||
subsystem_vendor;
|
||||
id = ((u32) card->
|
||||
subsystem_device << 16) | card->subsystem_vendor;
|
||||
for (i = 0; i < n_boardtypes; i++) {
|
||||
if (boardtypes[i].id == id) {
|
||||
printk(" %s", boardtypes[i].name);
|
||||
@@ -768,7 +777,9 @@ static int daqboard2000_attach(struct comedi_device *dev, struct comedi_devconfi
|
||||
}
|
||||
}
|
||||
if (!dev->board_ptr) {
|
||||
printk(" unknown subsystem id %08x (pretend it is an ids2)", id);
|
||||
printk
|
||||
(" unknown subsystem id %08x (pretend it is an ids2)",
|
||||
id);
|
||||
dev->board_ptr = boardtypes;
|
||||
}
|
||||
}
|
||||
@@ -780,9 +791,9 @@ static int daqboard2000_attach(struct comedi_device *dev, struct comedi_devconfi
|
||||
}
|
||||
devpriv->got_regions = 1;
|
||||
devpriv->plx =
|
||||
ioremap(pci_resource_start(card, 0), DAQBOARD2000_PLX_SIZE);
|
||||
ioremap(pci_resource_start(card, 0), DAQBOARD2000_PLX_SIZE);
|
||||
devpriv->daq =
|
||||
ioremap(pci_resource_start(card, 2), DAQBOARD2000_DAQ_SIZE);
|
||||
ioremap(pci_resource_start(card, 2), DAQBOARD2000_DAQ_SIZE);
|
||||
if (!devpriv->plx || !devpriv->daq) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
@@ -844,10 +855,10 @@ static int daqboard2000_attach(struct comedi_device *dev, struct comedi_devconfi
|
||||
|
||||
s = dev->subdevices + 2;
|
||||
result = subdev_8255_init(dev, s, daqboard2000_8255_cb,
|
||||
(unsigned long)(dev->iobase + 0x40));
|
||||
(unsigned long)(dev->iobase + 0x40));
|
||||
|
||||
printk("\n");
|
||||
out:
|
||||
out:
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -155,60 +155,66 @@ driver.
|
||||
/* gainlist same as _pgx_ below */
|
||||
|
||||
static int das08_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int das08_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int das08_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int das08jr_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int das08jr_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int das08jr_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int das08ao_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int das08jr_di_rbits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int das08jr_do_wbits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int das08jr_ao_winsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int das08ao_ao_winsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static void i8254_set_mode_low(unsigned int base, int channel,
|
||||
unsigned int mode);
|
||||
unsigned int mode);
|
||||
|
||||
static const struct comedi_lrange range_das08_pgl = { 9, {
|
||||
BIP_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(2.5),
|
||||
BIP_RANGE(1.25),
|
||||
BIP_RANGE(0.625),
|
||||
UNI_RANGE(10),
|
||||
UNI_RANGE(5),
|
||||
UNI_RANGE(2.5),
|
||||
UNI_RANGE(1.25)
|
||||
}
|
||||
BIP_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(2.5),
|
||||
BIP_RANGE(1.25),
|
||||
BIP_RANGE(0.625),
|
||||
UNI_RANGE(10),
|
||||
UNI_RANGE(5),
|
||||
UNI_RANGE(2.5),
|
||||
UNI_RANGE(1.25)
|
||||
}
|
||||
};
|
||||
|
||||
static const struct comedi_lrange range_das08_pgh = { 12, {
|
||||
BIP_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(1),
|
||||
BIP_RANGE(0.5),
|
||||
BIP_RANGE(0.1),
|
||||
BIP_RANGE(0.05),
|
||||
BIP_RANGE(0.01),
|
||||
BIP_RANGE(0.005),
|
||||
UNI_RANGE(10),
|
||||
UNI_RANGE(1),
|
||||
UNI_RANGE(0.1),
|
||||
UNI_RANGE(0.01),
|
||||
}
|
||||
BIP_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(1),
|
||||
BIP_RANGE(0.5),
|
||||
BIP_RANGE(0.1),
|
||||
BIP_RANGE(0.05),
|
||||
BIP_RANGE(0.01),
|
||||
BIP_RANGE(0.005),
|
||||
UNI_RANGE(10),
|
||||
UNI_RANGE(1),
|
||||
UNI_RANGE(0.1),
|
||||
UNI_RANGE(0.01),
|
||||
}
|
||||
};
|
||||
|
||||
static const struct comedi_lrange range_das08_pgm = { 9, {
|
||||
BIP_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(0.5),
|
||||
BIP_RANGE(0.05),
|
||||
BIP_RANGE(0.01),
|
||||
UNI_RANGE(10),
|
||||
UNI_RANGE(1),
|
||||
UNI_RANGE(0.1),
|
||||
UNI_RANGE(0.01)
|
||||
}
|
||||
BIP_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(0.5),
|
||||
BIP_RANGE(0.05),
|
||||
BIP_RANGE(0.01),
|
||||
UNI_RANGE(10),
|
||||
UNI_RANGE(1),
|
||||
UNI_RANGE(0.1),
|
||||
UNI_RANGE(0.01)
|
||||
}
|
||||
}; /*
|
||||
cio-das08jr.pdf
|
||||
|
||||
@@ -234,7 +240,7 @@ static const struct comedi_lrange *const das08_ai_lranges[] = {
|
||||
};
|
||||
|
||||
static const int das08_pgh_gainlist[] =
|
||||
{ 8, 0, 10, 2, 12, 4, 14, 6, 1, 3, 5, 7 };
|
||||
{ 8, 0, 10, 2, 12, 4, 14, 6, 1, 3, 5, 7 };
|
||||
static const int das08_pgl_gainlist[] = { 8, 0, 2, 4, 6, 1, 3, 5, 7 };
|
||||
static const int das08_pgm_gainlist[] = { 8, 0, 10, 12, 14, 9, 11, 13, 15 };
|
||||
|
||||
@@ -248,260 +254,261 @@ static const int *const das08_gainlists[] = {
|
||||
|
||||
static const struct das08_board_struct das08_boards[] = {
|
||||
{
|
||||
.name = "isa-das08", /* cio-das08.pdf */
|
||||
.bustype = isa,
|
||||
.ai = das08_ai_rinsn,
|
||||
.ai_nbits = 12,
|
||||
.ai_pg = das08_pg_none,
|
||||
.ai_encoding = das08_encode12,
|
||||
.ao = NULL,
|
||||
.ao_nbits = 12,
|
||||
.di = das08_di_rbits,
|
||||
.do_ = das08_do_wbits,
|
||||
.do_nchan = 4,
|
||||
.i8255_offset = 8,
|
||||
.i8254_offset = 4,
|
||||
.iosize = 16, /* unchecked */
|
||||
},
|
||||
.name = "isa-das08", /* cio-das08.pdf */
|
||||
.bustype = isa,
|
||||
.ai = das08_ai_rinsn,
|
||||
.ai_nbits = 12,
|
||||
.ai_pg = das08_pg_none,
|
||||
.ai_encoding = das08_encode12,
|
||||
.ao = NULL,
|
||||
.ao_nbits = 12,
|
||||
.di = das08_di_rbits,
|
||||
.do_ = das08_do_wbits,
|
||||
.do_nchan = 4,
|
||||
.i8255_offset = 8,
|
||||
.i8254_offset = 4,
|
||||
.iosize = 16, /* unchecked */
|
||||
},
|
||||
{
|
||||
.name = "das08-pgm", /* cio-das08pgx.pdf */
|
||||
.bustype = isa,
|
||||
.ai = das08_ai_rinsn,
|
||||
.ai_nbits = 12,
|
||||
.ai_pg = das08_pgm,
|
||||
.ai_encoding = das08_encode12,
|
||||
.ao = NULL,
|
||||
.di = das08_di_rbits,
|
||||
.do_ = das08_do_wbits,
|
||||
.do_nchan = 4,
|
||||
.i8255_offset = 0,
|
||||
.i8254_offset = 0x04,
|
||||
.iosize = 16, /* unchecked */
|
||||
},
|
||||
.name = "das08-pgm", /* cio-das08pgx.pdf */
|
||||
.bustype = isa,
|
||||
.ai = das08_ai_rinsn,
|
||||
.ai_nbits = 12,
|
||||
.ai_pg = das08_pgm,
|
||||
.ai_encoding = das08_encode12,
|
||||
.ao = NULL,
|
||||
.di = das08_di_rbits,
|
||||
.do_ = das08_do_wbits,
|
||||
.do_nchan = 4,
|
||||
.i8255_offset = 0,
|
||||
.i8254_offset = 0x04,
|
||||
.iosize = 16, /* unchecked */
|
||||
},
|
||||
{
|
||||
.name = "das08-pgh", /* cio-das08pgx.pdf */
|
||||
.bustype = isa,
|
||||
.ai = das08_ai_rinsn,
|
||||
.ai_nbits = 12,
|
||||
.ai_pg = das08_pgh,
|
||||
.ai_encoding = das08_encode12,
|
||||
.ao = NULL,
|
||||
.di = das08_di_rbits,
|
||||
.do_ = das08_do_wbits,
|
||||
.do_nchan = 4,
|
||||
.i8255_offset = 0,
|
||||
.i8254_offset = 0x04,
|
||||
.iosize = 16, /* unchecked */
|
||||
},
|
||||
.name = "das08-pgh", /* cio-das08pgx.pdf */
|
||||
.bustype = isa,
|
||||
.ai = das08_ai_rinsn,
|
||||
.ai_nbits = 12,
|
||||
.ai_pg = das08_pgh,
|
||||
.ai_encoding = das08_encode12,
|
||||
.ao = NULL,
|
||||
.di = das08_di_rbits,
|
||||
.do_ = das08_do_wbits,
|
||||
.do_nchan = 4,
|
||||
.i8255_offset = 0,
|
||||
.i8254_offset = 0x04,
|
||||
.iosize = 16, /* unchecked */
|
||||
},
|
||||
{
|
||||
.name = "das08-pgl", /* cio-das08pgx.pdf */
|
||||
.bustype = isa,
|
||||
.ai = das08_ai_rinsn,
|
||||
.ai_nbits = 12,
|
||||
.ai_pg = das08_pgl,
|
||||
.ai_encoding = das08_encode12,
|
||||
.ao = NULL,
|
||||
.di = das08_di_rbits,
|
||||
.do_ = das08_do_wbits,
|
||||
.do_nchan = 4,
|
||||
.i8255_offset = 0,
|
||||
.i8254_offset = 0x04,
|
||||
.iosize = 16, /* unchecked */
|
||||
},
|
||||
.name = "das08-pgl", /* cio-das08pgx.pdf */
|
||||
.bustype = isa,
|
||||
.ai = das08_ai_rinsn,
|
||||
.ai_nbits = 12,
|
||||
.ai_pg = das08_pgl,
|
||||
.ai_encoding = das08_encode12,
|
||||
.ao = NULL,
|
||||
.di = das08_di_rbits,
|
||||
.do_ = das08_do_wbits,
|
||||
.do_nchan = 4,
|
||||
.i8255_offset = 0,
|
||||
.i8254_offset = 0x04,
|
||||
.iosize = 16, /* unchecked */
|
||||
},
|
||||
{
|
||||
.name = "das08-aoh", /* cio-das08_aox.pdf */
|
||||
.bustype = isa,
|
||||
.ai = das08_ai_rinsn,
|
||||
.ai_nbits = 12,
|
||||
.ai_pg = das08_pgh,
|
||||
.ai_encoding = das08_encode12,
|
||||
.ao = das08ao_ao_winsn, /* 8 */
|
||||
.ao_nbits = 12,
|
||||
.di = das08_di_rbits,
|
||||
.do_ = das08_do_wbits,
|
||||
.do_nchan = 4,
|
||||
.i8255_offset = 0x0c,
|
||||
.i8254_offset = 0x04,
|
||||
.iosize = 16, /* unchecked */
|
||||
},
|
||||
.name = "das08-aoh", /* cio-das08_aox.pdf */
|
||||
.bustype = isa,
|
||||
.ai = das08_ai_rinsn,
|
||||
.ai_nbits = 12,
|
||||
.ai_pg = das08_pgh,
|
||||
.ai_encoding = das08_encode12,
|
||||
.ao = das08ao_ao_winsn, /* 8 */
|
||||
.ao_nbits = 12,
|
||||
.di = das08_di_rbits,
|
||||
.do_ = das08_do_wbits,
|
||||
.do_nchan = 4,
|
||||
.i8255_offset = 0x0c,
|
||||
.i8254_offset = 0x04,
|
||||
.iosize = 16, /* unchecked */
|
||||
},
|
||||
{
|
||||
.name = "das08-aol", /* cio-das08_aox.pdf */
|
||||
.bustype = isa,
|
||||
.ai = das08_ai_rinsn,
|
||||
.ai_nbits = 12,
|
||||
.ai_pg = das08_pgl,
|
||||
.ai_encoding = das08_encode12,
|
||||
.ao = das08ao_ao_winsn, /* 8 */
|
||||
.ao_nbits = 12,
|
||||
.di = das08_di_rbits,
|
||||
.do_ = das08_do_wbits,
|
||||
.do_nchan = 4,
|
||||
.i8255_offset = 0x0c,
|
||||
.i8254_offset = 0x04,
|
||||
.iosize = 16, /* unchecked */
|
||||
},
|
||||
.name = "das08-aol", /* cio-das08_aox.pdf */
|
||||
.bustype = isa,
|
||||
.ai = das08_ai_rinsn,
|
||||
.ai_nbits = 12,
|
||||
.ai_pg = das08_pgl,
|
||||
.ai_encoding = das08_encode12,
|
||||
.ao = das08ao_ao_winsn, /* 8 */
|
||||
.ao_nbits = 12,
|
||||
.di = das08_di_rbits,
|
||||
.do_ = das08_do_wbits,
|
||||
.do_nchan = 4,
|
||||
.i8255_offset = 0x0c,
|
||||
.i8254_offset = 0x04,
|
||||
.iosize = 16, /* unchecked */
|
||||
},
|
||||
{
|
||||
.name = "das08-aom", /* cio-das08_aox.pdf */
|
||||
.bustype = isa,
|
||||
.ai = das08_ai_rinsn,
|
||||
.ai_nbits = 12,
|
||||
.ai_pg = das08_pgm,
|
||||
.ai_encoding = das08_encode12,
|
||||
.ao = das08ao_ao_winsn, /* 8 */
|
||||
.ao_nbits = 12,
|
||||
.di = das08_di_rbits,
|
||||
.do_ = das08_do_wbits,
|
||||
.do_nchan = 4,
|
||||
.i8255_offset = 0x0c,
|
||||
.i8254_offset = 0x04,
|
||||
.iosize = 16, /* unchecked */
|
||||
},
|
||||
.name = "das08-aom", /* cio-das08_aox.pdf */
|
||||
.bustype = isa,
|
||||
.ai = das08_ai_rinsn,
|
||||
.ai_nbits = 12,
|
||||
.ai_pg = das08_pgm,
|
||||
.ai_encoding = das08_encode12,
|
||||
.ao = das08ao_ao_winsn, /* 8 */
|
||||
.ao_nbits = 12,
|
||||
.di = das08_di_rbits,
|
||||
.do_ = das08_do_wbits,
|
||||
.do_nchan = 4,
|
||||
.i8255_offset = 0x0c,
|
||||
.i8254_offset = 0x04,
|
||||
.iosize = 16, /* unchecked */
|
||||
},
|
||||
{
|
||||
.name = "das08/jr-ao", /* cio-das08-jr-ao.pdf */
|
||||
.bustype = isa,
|
||||
.ai = das08_ai_rinsn,
|
||||
.ai_nbits = 12,
|
||||
.ai_pg = das08_pg_none,
|
||||
.ai_encoding = das08_encode12,
|
||||
.ao = das08jr_ao_winsn,
|
||||
.ao_nbits = 12,
|
||||
.di = das08jr_di_rbits,
|
||||
.do_ = das08jr_do_wbits,
|
||||
.do_nchan = 8,
|
||||
.i8255_offset = 0,
|
||||
.i8254_offset = 0,
|
||||
.iosize = 16, /* unchecked */
|
||||
},
|
||||
.name = "das08/jr-ao", /* cio-das08-jr-ao.pdf */
|
||||
.bustype = isa,
|
||||
.ai = das08_ai_rinsn,
|
||||
.ai_nbits = 12,
|
||||
.ai_pg = das08_pg_none,
|
||||
.ai_encoding = das08_encode12,
|
||||
.ao = das08jr_ao_winsn,
|
||||
.ao_nbits = 12,
|
||||
.di = das08jr_di_rbits,
|
||||
.do_ = das08jr_do_wbits,
|
||||
.do_nchan = 8,
|
||||
.i8255_offset = 0,
|
||||
.i8254_offset = 0,
|
||||
.iosize = 16, /* unchecked */
|
||||
},
|
||||
{
|
||||
.name = "das08jr-16-ao", /* cio-das08jr-16-ao.pdf */
|
||||
.bustype = isa,
|
||||
.ai = das08_ai_rinsn,
|
||||
.ai_nbits = 16,
|
||||
.ai_pg = das08_pg_none,
|
||||
.ai_encoding = das08_encode12,
|
||||
.ao = das08jr_ao_winsn,
|
||||
.ao_nbits = 16,
|
||||
.di = das08jr_di_rbits,
|
||||
.do_ = das08jr_do_wbits,
|
||||
.do_nchan = 8,
|
||||
.i8255_offset = 0,
|
||||
.i8254_offset = 0x04,
|
||||
.iosize = 16, /* unchecked */
|
||||
},
|
||||
.name = "das08jr-16-ao", /* cio-das08jr-16-ao.pdf */
|
||||
.bustype = isa,
|
||||
.ai = das08_ai_rinsn,
|
||||
.ai_nbits = 16,
|
||||
.ai_pg = das08_pg_none,
|
||||
.ai_encoding = das08_encode12,
|
||||
.ao = das08jr_ao_winsn,
|
||||
.ao_nbits = 16,
|
||||
.di = das08jr_di_rbits,
|
||||
.do_ = das08jr_do_wbits,
|
||||
.do_nchan = 8,
|
||||
.i8255_offset = 0,
|
||||
.i8254_offset = 0x04,
|
||||
.iosize = 16, /* unchecked */
|
||||
},
|
||||
#ifdef CONFIG_COMEDI_PCI
|
||||
{
|
||||
.name = "das08", /* pci-das08 */
|
||||
.id = PCI_DEVICE_ID_PCIDAS08,
|
||||
.bustype = pci,
|
||||
.ai = das08_ai_rinsn,
|
||||
.ai_nbits = 12,
|
||||
.ai_pg = das08_bipolar5,
|
||||
.ai_encoding = das08_encode12,
|
||||
.ao = NULL,
|
||||
.ao_nbits = 0,
|
||||
.di = das08_di_rbits,
|
||||
.do_ = das08_do_wbits,
|
||||
.do_nchan = 4,
|
||||
.i8255_offset = 0,
|
||||
.i8254_offset = 4,
|
||||
.iosize = 8,
|
||||
},
|
||||
.name = "das08", /* pci-das08 */
|
||||
.id = PCI_DEVICE_ID_PCIDAS08,
|
||||
.bustype = pci,
|
||||
.ai = das08_ai_rinsn,
|
||||
.ai_nbits = 12,
|
||||
.ai_pg = das08_bipolar5,
|
||||
.ai_encoding = das08_encode12,
|
||||
.ao = NULL,
|
||||
.ao_nbits = 0,
|
||||
.di = das08_di_rbits,
|
||||
.do_ = das08_do_wbits,
|
||||
.do_nchan = 4,
|
||||
.i8255_offset = 0,
|
||||
.i8254_offset = 4,
|
||||
.iosize = 8,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
.name = "pc104-das08",
|
||||
.bustype = pc104,
|
||||
.ai = das08_ai_rinsn,
|
||||
.ai_nbits = 12,
|
||||
.ai_pg = das08_pg_none,
|
||||
.ai_encoding = das08_encode12,
|
||||
.ao = NULL,
|
||||
.ao_nbits = 0,
|
||||
.di = das08_di_rbits,
|
||||
.do_ = das08_do_wbits,
|
||||
.do_nchan = 4,
|
||||
.i8255_offset = 0,
|
||||
.i8254_offset = 4,
|
||||
.iosize = 16, /* unchecked */
|
||||
},
|
||||
.name = "pc104-das08",
|
||||
.bustype = pc104,
|
||||
.ai = das08_ai_rinsn,
|
||||
.ai_nbits = 12,
|
||||
.ai_pg = das08_pg_none,
|
||||
.ai_encoding = das08_encode12,
|
||||
.ao = NULL,
|
||||
.ao_nbits = 0,
|
||||
.di = das08_di_rbits,
|
||||
.do_ = das08_do_wbits,
|
||||
.do_nchan = 4,
|
||||
.i8255_offset = 0,
|
||||
.i8254_offset = 4,
|
||||
.iosize = 16, /* unchecked */
|
||||
},
|
||||
#if 0
|
||||
{
|
||||
.name = "das08/f",
|
||||
},
|
||||
.name = "das08/f",
|
||||
},
|
||||
{
|
||||
.name = "das08jr",
|
||||
},
|
||||
.name = "das08jr",
|
||||
},
|
||||
#endif
|
||||
{
|
||||
.name = "das08jr/16",
|
||||
.bustype = isa,
|
||||
.ai = das08_ai_rinsn,
|
||||
.ai_nbits = 16,
|
||||
.ai_pg = das08_pg_none,
|
||||
.ai_encoding = das08_encode16,
|
||||
.ao = NULL,
|
||||
.ao_nbits = 0,
|
||||
.di = das08jr_di_rbits,
|
||||
.do_ = das08jr_do_wbits,
|
||||
.do_nchan = 8,
|
||||
.i8255_offset = 0,
|
||||
.i8254_offset = 0,
|
||||
.iosize = 16, /* unchecked */
|
||||
},
|
||||
.name = "das08jr/16",
|
||||
.bustype = isa,
|
||||
.ai = das08_ai_rinsn,
|
||||
.ai_nbits = 16,
|
||||
.ai_pg = das08_pg_none,
|
||||
.ai_encoding = das08_encode16,
|
||||
.ao = NULL,
|
||||
.ao_nbits = 0,
|
||||
.di = das08jr_di_rbits,
|
||||
.do_ = das08jr_do_wbits,
|
||||
.do_nchan = 8,
|
||||
.i8255_offset = 0,
|
||||
.i8254_offset = 0,
|
||||
.iosize = 16, /* unchecked */
|
||||
},
|
||||
#if 0
|
||||
{
|
||||
.name = "das48-pga", /* cio-das48-pga.pdf */
|
||||
},
|
||||
.name = "das48-pga", /* cio-das48-pga.pdf */
|
||||
},
|
||||
{
|
||||
.name = "das08-pga-g2", /* a KM board */
|
||||
},
|
||||
.name = "das08-pga-g2", /* a KM board */
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef CONFIG_COMEDI_PCMCIA
|
||||
struct das08_board_struct das08_cs_boards[NUM_DAS08_CS_BOARDS] = {
|
||||
{
|
||||
.name = "pcm-das08",
|
||||
.id = 0x0, /* XXX */
|
||||
.bustype = pcmcia,
|
||||
.ai = das08_ai_rinsn,
|
||||
.ai_nbits = 12,
|
||||
.ai_pg = das08_bipolar5,
|
||||
.ai_encoding = das08_pcm_encode12,
|
||||
.ao = NULL,
|
||||
.ao_nbits = 0,
|
||||
.di = das08_di_rbits,
|
||||
.do_ = das08_do_wbits,
|
||||
.do_nchan = 3,
|
||||
.i8255_offset = 0,
|
||||
.i8254_offset = 0,
|
||||
.iosize = 16,
|
||||
},
|
||||
.name = "pcm-das08",
|
||||
.id = 0x0, /* XXX */
|
||||
.bustype = pcmcia,
|
||||
.ai = das08_ai_rinsn,
|
||||
.ai_nbits = 12,
|
||||
.ai_pg = das08_bipolar5,
|
||||
.ai_encoding = das08_pcm_encode12,
|
||||
.ao = NULL,
|
||||
.ao_nbits = 0,
|
||||
.di = das08_di_rbits,
|
||||
.do_ = das08_do_wbits,
|
||||
.do_nchan = 3,
|
||||
.i8255_offset = 0,
|
||||
.i8254_offset = 0,
|
||||
.iosize = 16,
|
||||
},
|
||||
/* duplicate so driver name can be used also */
|
||||
{
|
||||
.name = "das08_cs",
|
||||
.id = 0x0, /* XXX */
|
||||
.bustype = pcmcia,
|
||||
.ai = das08_ai_rinsn,
|
||||
.ai_nbits = 12,
|
||||
.ai_pg = das08_bipolar5,
|
||||
.ai_encoding = das08_pcm_encode12,
|
||||
.ao = NULL,
|
||||
.ao_nbits = 0,
|
||||
.di = das08_di_rbits,
|
||||
.do_ = das08_do_wbits,
|
||||
.do_nchan = 3,
|
||||
.i8255_offset = 0,
|
||||
.i8254_offset = 0,
|
||||
.iosize = 16,
|
||||
},
|
||||
.name = "das08_cs",
|
||||
.id = 0x0, /* XXX */
|
||||
.bustype = pcmcia,
|
||||
.ai = das08_ai_rinsn,
|
||||
.ai_nbits = 12,
|
||||
.ai_pg = das08_bipolar5,
|
||||
.ai_encoding = das08_pcm_encode12,
|
||||
.ao = NULL,
|
||||
.ao_nbits = 0,
|
||||
.di = das08_di_rbits,
|
||||
.do_ = das08_do_wbits,
|
||||
.do_nchan = 3,
|
||||
.i8255_offset = 0,
|
||||
.i8254_offset = 0,
|
||||
.iosize = 16,
|
||||
},
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_COMEDI_PCI
|
||||
static DEFINE_PCI_DEVICE_TABLE(das08_pci_table) = {
|
||||
{PCI_VENDOR_ID_COMPUTERBOARDS, PCI_DEVICE_ID_PCIDAS08, PCI_ANY_ID,
|
||||
PCI_ANY_ID, 0, 0, 0},
|
||||
{0}
|
||||
{
|
||||
PCI_VENDOR_ID_COMPUTERBOARDS, PCI_DEVICE_ID_PCIDAS08,
|
||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
0}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, das08_pci_table);
|
||||
@@ -513,7 +520,7 @@ MODULE_DEVICE_TABLE(pci, das08_pci_table);
|
||||
#define TIMEOUT 100000
|
||||
|
||||
static int das08_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int i, n;
|
||||
int chan;
|
||||
@@ -538,7 +545,7 @@ static int das08_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
/* set gain/range */
|
||||
range = CR_RANGE(insn->chanspec);
|
||||
outb(devpriv->pg_gainlist[range],
|
||||
dev->iobase + DAS08AO_GAIN_CONTROL);
|
||||
dev->iobase + DAS08AO_GAIN_CONTROL);
|
||||
}
|
||||
|
||||
for (n = 0; n < insn->n; n++) {
|
||||
@@ -580,7 +587,7 @@ static int das08_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
}
|
||||
|
||||
static int das08_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
data[0] = 0;
|
||||
data[1] = DAS08_IP(inb(dev->iobase + DAS08_STATUS));
|
||||
@@ -589,7 +596,7 @@ static int das08_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
}
|
||||
|
||||
static int das08_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int wbits;
|
||||
|
||||
@@ -611,8 +618,9 @@ static int das08_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int das08jr_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int das08jr_di_rbits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
data[0] = 0;
|
||||
data[1] = inb(dev->iobase + DAS08JR_DIO);
|
||||
@@ -620,8 +628,9 @@ static int das08jr_di_rbits(struct comedi_device *dev, struct comedi_subdevice *
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int das08jr_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int das08jr_do_wbits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
/* null bits we are going to set */
|
||||
devpriv->do_bits &= ~data[0];
|
||||
@@ -634,8 +643,9 @@ static int das08jr_do_wbits(struct comedi_device *dev, struct comedi_subdevice *
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int das08jr_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int das08jr_ao_winsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int n;
|
||||
int lsb, msb;
|
||||
@@ -668,8 +678,9 @@ static int das08jr_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *
|
||||
* a different method to force an update.
|
||||
*
|
||||
*/
|
||||
static int das08ao_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int das08ao_ao_winsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int n;
|
||||
int lsb, msb;
|
||||
@@ -716,7 +727,7 @@ static unsigned int i8254_read_channel_low(unsigned int base, int chan)
|
||||
}
|
||||
|
||||
static void i8254_write_channel_low(unsigned int base, int chan,
|
||||
unsigned int value)
|
||||
unsigned int value)
|
||||
{
|
||||
unsigned int msb, lsb;
|
||||
|
||||
@@ -740,7 +751,7 @@ static unsigned int i8254_read_channel(struct i8254_struct *st, int channel)
|
||||
}
|
||||
|
||||
static void i8254_write_channel(struct i8254_struct *st, int channel,
|
||||
unsigned int value)
|
||||
unsigned int value)
|
||||
{
|
||||
int chan = st->logic2phys[channel];
|
||||
|
||||
@@ -755,13 +766,13 @@ static void i8254_initialize(struct i8254_struct *st)
|
||||
}
|
||||
|
||||
static void i8254_set_mode_low(unsigned int base, int channel,
|
||||
unsigned int mode)
|
||||
unsigned int mode)
|
||||
{
|
||||
outb((channel << 6) | 0x30 | (mode & 0x0F), base + I8254_CTRL);
|
||||
}
|
||||
|
||||
static void i8254_set_mode(struct i8254_struct *st, int channel,
|
||||
unsigned int mode)
|
||||
unsigned int mode)
|
||||
{
|
||||
int chan = st->logic2phys[channel];
|
||||
|
||||
@@ -782,8 +793,9 @@ static unsigned int i8254_read_status(struct i8254_struct *st, int channel)
|
||||
return i8254_read_status_low(st->iobase, chan);
|
||||
}
|
||||
|
||||
static int das08_counter_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int das08_counter_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int chan = insn->chanspec;
|
||||
|
||||
@@ -794,8 +806,9 @@ static int das08_counter_read(struct comedi_device *dev, struct comedi_subdevice
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int das08_counter_write(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int das08_counter_write(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int chan = insn->chanspec;
|
||||
|
||||
@@ -805,8 +818,9 @@ static int das08_counter_write(struct comedi_device *dev, struct comedi_subdevic
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int das08_counter_config(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int das08_counter_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int chan = insn->chanspec;
|
||||
|
||||
@@ -835,8 +849,7 @@ static struct comedi_driver driver_das08 = {
|
||||
.attach = das08_attach,
|
||||
.detach = das08_common_detach,
|
||||
.board_name = &das08_boards[0].name,
|
||||
.num_names = sizeof(das08_boards) /
|
||||
sizeof(struct das08_board_struct),
|
||||
.num_names = sizeof(das08_boards) / sizeof(struct das08_board_struct),
|
||||
.offset = sizeof(struct das08_board_struct),
|
||||
};
|
||||
|
||||
@@ -921,7 +934,8 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase)
|
||||
/* 8255 */
|
||||
if (thisboard->i8255_offset != 0) {
|
||||
subdev_8255_init(dev, s, NULL, (unsigned long)(dev->iobase +
|
||||
thisboard->i8255_offset));
|
||||
thisboard->
|
||||
i8255_offset));
|
||||
} else {
|
||||
s->type = COMEDI_SUBD_UNUSED;
|
||||
}
|
||||
@@ -943,8 +957,8 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase)
|
||||
devpriv->i8254.logic2phys[2] = 2;
|
||||
devpriv->i8254.iobase = iobase + thisboard->i8254_offset;
|
||||
devpriv->i8254.mode[0] =
|
||||
devpriv->i8254.mode[1] =
|
||||
devpriv->i8254.mode[2] = I8254_MODE0 | I8254_BINARY;
|
||||
devpriv->i8254.mode[1] =
|
||||
devpriv->i8254.mode[2] = I8254_MODE0 | I8254_BINARY;
|
||||
i8254_initialize(&devpriv->i8254);
|
||||
} else {
|
||||
s->type = COMEDI_SUBD_UNUSED;
|
||||
@@ -972,19 +986,19 @@ static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
#ifdef CONFIG_COMEDI_PCI
|
||||
if (it->options[0] || it->options[1]) {
|
||||
printk("bus %i slot %i ",
|
||||
it->options[0], it->options[1]);
|
||||
it->options[0], it->options[1]);
|
||||
}
|
||||
printk("\n");
|
||||
/* find card */
|
||||
for (pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
|
||||
pdev != NULL;
|
||||
pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) {
|
||||
pdev != NULL;
|
||||
pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) {
|
||||
if (pdev->vendor == PCI_VENDOR_ID_COMPUTERBOARDS
|
||||
&& pdev->device == PCI_DEVICE_ID_PCIDAS08) {
|
||||
&& pdev->device == PCI_DEVICE_ID_PCIDAS08) {
|
||||
if (it->options[0] || it->options[1]) {
|
||||
if (pdev->bus->number == it->options[0]
|
||||
&& PCI_SLOT(pdev->devfn) ==
|
||||
it->options[1]) {
|
||||
&& PCI_SLOT(pdev->devfn) ==
|
||||
it->options[1]) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@@ -999,7 +1013,8 @@ static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
devpriv->pdev = pdev;
|
||||
/* enable PCI device and reserve I/O spaces */
|
||||
if (comedi_pci_enable(pdev, DRV_NAME)) {
|
||||
printk(" Error enabling PCI device and requesting regions\n");
|
||||
printk
|
||||
(" Error enabling PCI device and requesting regions\n");
|
||||
return -EIO;
|
||||
}
|
||||
/* read base addresses */
|
||||
@@ -1018,10 +1033,10 @@ static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
/* Enable local interrupt 1 and pci interrupt */
|
||||
outw(INTR1_ENABLE | PCI_INTR_ENABLE, pci_iobase + INTCSR);
|
||||
#endif
|
||||
#else /* CONFIG_COMEDI_PCI */
|
||||
#else /* CONFIG_COMEDI_PCI */
|
||||
printk("this driver has not been built with PCI support.\n");
|
||||
return -EINVAL;
|
||||
#endif /* CONFIG_COMEDI_PCI */
|
||||
#endif /* CONFIG_COMEDI_PCI */
|
||||
} else {
|
||||
iobase = it->options[0];
|
||||
}
|
||||
@@ -1042,7 +1057,6 @@ int das08_common_detach(struct comedi_device *dev)
|
||||
if (dev->iobase)
|
||||
release_region(dev->iobase, thisboard->iosize);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMEDI_PCI
|
||||
if (devpriv) {
|
||||
if (devpriv->pdev) {
|
||||
|
||||
@@ -28,7 +28,8 @@ enum das08_bustype { isa, pci, pcmcia, pc104 };
|
||||
/* different ways ai data is encoded in first two registers */
|
||||
enum das08_ai_encoding { das08_encode12, das08_encode16, das08_pcm_encode12 };
|
||||
enum das08_lrange { das08_pg_none, das08_bipolar5, das08_pgh, das08_pgl,
|
||||
das08_pgm };
|
||||
das08_pgm
|
||||
};
|
||||
|
||||
struct das08_board_struct {
|
||||
const char *name;
|
||||
|
||||
@@ -56,7 +56,8 @@ static struct pcmcia_device *cur_dev = NULL;
|
||||
|
||||
#define thisboard ((const struct das08_board_struct *)dev->board_ptr)
|
||||
|
||||
static int das08_cs_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int das08_cs_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
|
||||
static struct comedi_driver driver_das08_cs = {
|
||||
.driver_name = "das08_cs",
|
||||
@@ -64,12 +65,12 @@ static struct comedi_driver driver_das08_cs = {
|
||||
.attach = das08_cs_attach,
|
||||
.detach = das08_common_detach,
|
||||
.board_name = &das08_cs_boards[0].name,
|
||||
.num_names = sizeof(das08_cs_boards) /
|
||||
sizeof(struct das08_board_struct),
|
||||
.num_names = ARRAY_SIZE(das08_cs_boards),
|
||||
.offset = sizeof(struct das08_board_struct),
|
||||
};
|
||||
|
||||
static int das08_cs_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
static int das08_cs_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it)
|
||||
{
|
||||
int ret;
|
||||
unsigned long iobase;
|
||||
@@ -122,7 +123,7 @@ static int pc_debug = PCMCIA_DEBUG;
|
||||
module_param(pc_debug, int, 0644);
|
||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
|
||||
static const char *version =
|
||||
"das08.c pcmcia code (Frank Hess), modified from dummy_cs.c 1.31 2001/08/24 12:13:13 (David Hinds)";
|
||||
"das08.c pcmcia code (Frank Hess), modified from dummy_cs.c 1.31 2001/08/24 12:13:13 (David Hinds)";
|
||||
#else
|
||||
#define DEBUG(n, args...)
|
||||
#endif
|
||||
@@ -226,7 +227,7 @@ static void das08_pcmcia_detach(struct pcmcia_device *link)
|
||||
DEBUG(0, "das08_pcmcia_detach(0x%p)\n", link);
|
||||
|
||||
if (link->dev_node) {
|
||||
((struct local_info_t *) link->priv)->stop = 1;
|
||||
((struct local_info_t *)link->priv)->stop = 1;
|
||||
das08_pcmcia_release(link);
|
||||
}
|
||||
|
||||
@@ -356,7 +357,7 @@ static void das08_pcmcia_config(struct pcmcia_device *link)
|
||||
/* If we got this far, we're cool! */
|
||||
break;
|
||||
|
||||
next_entry:
|
||||
next_entry:
|
||||
last_fn = GetNextTuple;
|
||||
|
||||
last_ret = pcmcia_get_next_tuple(link, &tuple);
|
||||
@@ -391,20 +392,20 @@ static void das08_pcmcia_config(struct pcmcia_device *link)
|
||||
|
||||
/* Finally, report what we've done */
|
||||
printk(KERN_INFO "%s: index 0x%02x",
|
||||
dev->node.dev_name, link->conf.ConfigIndex);
|
||||
dev->node.dev_name, link->conf.ConfigIndex);
|
||||
if (link->conf.Attributes & CONF_ENABLE_IRQ)
|
||||
printk(", irq %u", link->irq.AssignedIRQ);
|
||||
if (link->io.NumPorts1)
|
||||
printk(", io 0x%04x-0x%04x", link->io.BasePort1,
|
||||
link->io.BasePort1 + link->io.NumPorts1 - 1);
|
||||
link->io.BasePort1 + link->io.NumPorts1 - 1);
|
||||
if (link->io.NumPorts2)
|
||||
printk(" & 0x%04x-0x%04x", link->io.BasePort2,
|
||||
link->io.BasePort2 + link->io.NumPorts2 - 1);
|
||||
link->io.BasePort2 + link->io.NumPorts2 - 1);
|
||||
printk("\n");
|
||||
|
||||
return;
|
||||
|
||||
cs_failed:
|
||||
cs_failed:
|
||||
cs_error(link, last_fn, last_ret);
|
||||
das08_pcmcia_release(link);
|
||||
|
||||
@@ -470,7 +471,7 @@ struct pcmcia_driver das08_cs_driver = {
|
||||
.id_table = das08_cs_id_table,
|
||||
.owner = THIS_MODULE,
|
||||
.drv = {
|
||||
.name = dev_info,
|
||||
.name = dev_info,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -120,36 +120,41 @@ irq can be omitted, although the cmd interface will not work without it.
|
||||
|
||||
static const struct comedi_lrange range_das16m1 = { 9,
|
||||
{
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(2.5),
|
||||
BIP_RANGE(1.25),
|
||||
BIP_RANGE(0.625),
|
||||
UNI_RANGE(10),
|
||||
UNI_RANGE(5),
|
||||
UNI_RANGE(2.5),
|
||||
UNI_RANGE(1.25),
|
||||
BIP_RANGE(10),
|
||||
}
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(2.5),
|
||||
BIP_RANGE(1.25),
|
||||
BIP_RANGE(0.625),
|
||||
UNI_RANGE(10),
|
||||
UNI_RANGE(5),
|
||||
UNI_RANGE(2.5),
|
||||
UNI_RANGE(1.25),
|
||||
BIP_RANGE(10),
|
||||
}
|
||||
};
|
||||
|
||||
static int das16m1_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int das16m1_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int das16m1_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int das16m1_do_wbits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int das16m1_di_rbits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int das16m1_ai_rinsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
static int das16m1_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd);
|
||||
static int das16m1_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s);
|
||||
static int das16m1_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
|
||||
static int das16m1_cmd_test(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_cmd *cmd);
|
||||
static int das16m1_cmd_exec(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s);
|
||||
static int das16m1_cancel(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s);
|
||||
|
||||
static int das16m1_poll(struct comedi_device *dev, struct comedi_subdevice *s);
|
||||
static irqreturn_t das16m1_interrupt(int irq, void *d);
|
||||
static void das16m1_handler(struct comedi_device *dev, unsigned int status);
|
||||
|
||||
static unsigned int das16m1_set_pacer(struct comedi_device *dev, unsigned int ns,
|
||||
int round_flag);
|
||||
static unsigned int das16m1_set_pacer(struct comedi_device *dev,
|
||||
unsigned int ns, int round_flag);
|
||||
|
||||
static int das16m1_irq_bits(unsigned int irq);
|
||||
|
||||
@@ -160,12 +165,13 @@ struct das16m1_board {
|
||||
|
||||
static const struct das16m1_board das16m1_boards[] = {
|
||||
{
|
||||
.name = "cio-das16/m1", /* CIO-DAS16_M1.pdf */
|
||||
.ai_speed = 1000, /* 1MHz max speed */
|
||||
},
|
||||
.name = "cio-das16/m1", /* CIO-DAS16_M1.pdf */
|
||||
.ai_speed = 1000, /* 1MHz max speed */
|
||||
},
|
||||
};
|
||||
|
||||
static int das16m1_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int das16m1_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int das16m1_detach(struct comedi_device *dev);
|
||||
static struct comedi_driver driver_das16m1 = {
|
||||
.driver_name = "das16m1",
|
||||
@@ -199,8 +205,8 @@ static inline short munge_sample(short data)
|
||||
return (data >> 4) & 0xfff;
|
||||
}
|
||||
|
||||
static int das16m1_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd)
|
||||
static int das16m1_cmd_test(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_cmd *cmd)
|
||||
{
|
||||
unsigned int err = 0, tmp, i;
|
||||
|
||||
@@ -289,8 +295,10 @@ static int das16m1_cmd_test(struct comedi_device *dev, struct comedi_subdevice *
|
||||
tmp = cmd->convert_arg;
|
||||
/* calculate counter values that give desired timing */
|
||||
i8253_cascade_ns_to_timer_2div(DAS16M1_XTAL,
|
||||
&(devpriv->divisor1), &(devpriv->divisor2),
|
||||
&(cmd->convert_arg), cmd->flags & TRIG_ROUND_MASK);
|
||||
&(devpriv->divisor1),
|
||||
&(devpriv->divisor2),
|
||||
&(cmd->convert_arg),
|
||||
cmd->flags & TRIG_ROUND_MASK);
|
||||
if (tmp != cmd->convert_arg)
|
||||
err++;
|
||||
}
|
||||
@@ -304,13 +312,13 @@ static int das16m1_cmd_test(struct comedi_device *dev, struct comedi_subdevice *
|
||||
/* even/odd channels must go into even/odd queue addresses */
|
||||
if ((i % 2) != (CR_CHAN(cmd->chanlist[i]) % 2)) {
|
||||
comedi_error(dev, "bad chanlist:\n"
|
||||
" even/odd channels must go have even/odd chanlist indices");
|
||||
" even/odd channels must go have even/odd chanlist indices");
|
||||
err++;
|
||||
}
|
||||
}
|
||||
if ((cmd->chanlist_len % 2) != 0) {
|
||||
comedi_error(dev,
|
||||
"chanlist must be of even length or length 1");
|
||||
"chanlist must be of even length or length 1");
|
||||
err++;
|
||||
}
|
||||
}
|
||||
@@ -321,7 +329,8 @@ static int das16m1_cmd_test(struct comedi_device *dev, struct comedi_subdevice *
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int das16m1_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
static int das16m1_cmd_exec(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
struct comedi_async *async = s->async;
|
||||
struct comedi_cmd *cmd = &async->cmd;
|
||||
@@ -345,20 +354,20 @@ static int das16m1_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *
|
||||
/* remember current reading of counter so we know when counter has
|
||||
* actually been loaded */
|
||||
devpriv->initial_hw_count =
|
||||
i8254_read(dev->iobase + DAS16M1_8254_FIRST, 0, 1);
|
||||
i8254_read(dev->iobase + DAS16M1_8254_FIRST, 0, 1);
|
||||
/* setup channel/gain queue */
|
||||
for (i = 0; i < cmd->chanlist_len; i++) {
|
||||
outb(i, dev->iobase + DAS16M1_QUEUE_ADDR);
|
||||
byte = Q_CHAN(CR_CHAN(cmd->
|
||||
chanlist[i])) | Q_RANGE(CR_RANGE(cmd->
|
||||
chanlist[i]));
|
||||
byte =
|
||||
Q_CHAN(CR_CHAN(cmd->chanlist[i])) |
|
||||
Q_RANGE(CR_RANGE(cmd->chanlist[i]));
|
||||
outb(byte, dev->iobase + DAS16M1_QUEUE_DATA);
|
||||
}
|
||||
|
||||
/* set counter mode and counts */
|
||||
cmd->convert_arg =
|
||||
das16m1_set_pacer(dev, cmd->convert_arg,
|
||||
cmd->flags & TRIG_ROUND_MASK);
|
||||
das16m1_set_pacer(dev, cmd->convert_arg,
|
||||
cmd->flags & TRIG_ROUND_MASK);
|
||||
|
||||
/* set control & status register */
|
||||
byte = 0;
|
||||
@@ -392,8 +401,9 @@ static int das16m1_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int das16m1_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int das16m1_ai_rinsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int i, n;
|
||||
int byte;
|
||||
@@ -405,8 +415,8 @@ static int das16m1_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *
|
||||
|
||||
/* setup channel/gain queue */
|
||||
outb(0, dev->iobase + DAS16M1_QUEUE_ADDR);
|
||||
byte = Q_CHAN(CR_CHAN(insn->chanspec)) | Q_RANGE(CR_RANGE(insn->
|
||||
chanspec));
|
||||
byte =
|
||||
Q_CHAN(CR_CHAN(insn->chanspec)) | Q_RANGE(CR_RANGE(insn->chanspec));
|
||||
outb(byte, dev->iobase + DAS16M1_QUEUE_DATA);
|
||||
|
||||
for (n = 0; n < insn->n; n++) {
|
||||
@@ -429,8 +439,9 @@ static int das16m1_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *
|
||||
return n;
|
||||
}
|
||||
|
||||
static int das16m1_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int das16m1_di_rbits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
unsigned int bits;
|
||||
|
||||
@@ -441,8 +452,9 @@ static int das16m1_di_rbits(struct comedi_device *dev, struct comedi_subdevice *
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int das16m1_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int das16m1_do_wbits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
unsigned int wbits;
|
||||
|
||||
@@ -552,7 +564,7 @@ static void das16m1_handler(struct comedi_device *dev, unsigned int status)
|
||||
insw(dev->iobase, devpriv->ai_buffer, num_samples);
|
||||
munge_sample_array(devpriv->ai_buffer, num_samples);
|
||||
cfc_write_array_to_buffer(s, devpriv->ai_buffer,
|
||||
num_samples * sizeof(short));
|
||||
num_samples * sizeof(short));
|
||||
devpriv->adc_count += num_samples;
|
||||
|
||||
if (cmd->stop_src == TRIG_COUNT) {
|
||||
@@ -577,17 +589,18 @@ static void das16m1_handler(struct comedi_device *dev, unsigned int status)
|
||||
/* This function takes a time in nanoseconds and sets the *
|
||||
* 2 pacer clocks to the closest frequency possible. It also *
|
||||
* returns the actual sampling period. */
|
||||
static unsigned int das16m1_set_pacer(struct comedi_device *dev, unsigned int ns,
|
||||
int rounding_flags)
|
||||
static unsigned int das16m1_set_pacer(struct comedi_device *dev,
|
||||
unsigned int ns, int rounding_flags)
|
||||
{
|
||||
i8253_cascade_ns_to_timer_2div(DAS16M1_XTAL, &(devpriv->divisor1),
|
||||
&(devpriv->divisor2), &ns, rounding_flags & TRIG_ROUND_MASK);
|
||||
&(devpriv->divisor2), &ns,
|
||||
rounding_flags & TRIG_ROUND_MASK);
|
||||
|
||||
/* Write the values of ctr1 and ctr2 into counters 1 and 2 */
|
||||
i8254_load(dev->iobase + DAS16M1_8254_SECOND, 0, 1, devpriv->divisor1,
|
||||
2);
|
||||
2);
|
||||
i8254_load(dev->iobase + DAS16M1_8254_SECOND, 0, 2, devpriv->divisor2,
|
||||
2);
|
||||
2);
|
||||
|
||||
return ns;
|
||||
}
|
||||
@@ -634,7 +647,8 @@ static int das16m1_irq_bits(unsigned int irq)
|
||||
* 1 IRQ
|
||||
*/
|
||||
|
||||
static int das16m1_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
static int das16m1_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it)
|
||||
{
|
||||
struct comedi_subdevice *s;
|
||||
int ret;
|
||||
@@ -652,14 +666,14 @@ static int das16m1_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
dev->board_name = thisboard->name;
|
||||
|
||||
printk(" io 0x%lx-0x%lx 0x%lx-0x%lx",
|
||||
iobase, iobase + DAS16M1_SIZE,
|
||||
iobase + DAS16M1_82C55, iobase + DAS16M1_82C55 + DAS16M1_SIZE2);
|
||||
iobase, iobase + DAS16M1_SIZE,
|
||||
iobase + DAS16M1_82C55, iobase + DAS16M1_82C55 + DAS16M1_SIZE2);
|
||||
if (!request_region(iobase, DAS16M1_SIZE, driver_das16m1.driver_name)) {
|
||||
printk(" I/O port conflict\n");
|
||||
return -EIO;
|
||||
}
|
||||
if (!request_region(iobase + DAS16M1_82C55, DAS16M1_SIZE2,
|
||||
driver_das16m1.driver_name)) {
|
||||
driver_das16m1.driver_name)) {
|
||||
release_region(iobase, DAS16M1_SIZE);
|
||||
printk(" I/O port conflict\n");
|
||||
return -EIO;
|
||||
@@ -682,7 +696,7 @@ static int das16m1_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
printk(", no irq\n");
|
||||
} else {
|
||||
printk(", invalid irq\n"
|
||||
" valid irqs are 2, 3, 5, 7, 10, 11, 12, or 15\n");
|
||||
" valid irqs are 2, 3, 5, 7, 10, 11, 12, or 15\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -99,7 +99,8 @@ This driver has suffered bitrot.
|
||||
#define C2 0x80
|
||||
#define RWLH 0x30
|
||||
|
||||
static int das6402_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int das6402_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int das6402_detach(struct comedi_device *dev);
|
||||
static struct comedi_driver driver_das6402 = {
|
||||
.driver_name = "das6402",
|
||||
@@ -117,7 +118,8 @@ struct das6402_private {
|
||||
};
|
||||
#define devpriv ((struct das6402_private *)dev->private)
|
||||
|
||||
static void das6402_ai_fifo_dregs(struct comedi_device *dev, struct comedi_subdevice *s);
|
||||
static void das6402_ai_fifo_dregs(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s);
|
||||
|
||||
static void das6402_setcounter(struct comedi_device *dev)
|
||||
{
|
||||
@@ -163,7 +165,7 @@ static irqreturn_t intr_handler(int irq, void *d)
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printk("das6402: interrupt! das6402_irqcount=%i\n",
|
||||
devpriv->das6402_irqcount);
|
||||
devpriv->das6402_irqcount);
|
||||
printk("das6402: iobase+2=%i\n", inw_p(dev->iobase + 2));
|
||||
#endif
|
||||
|
||||
@@ -174,7 +176,7 @@ static irqreturn_t intr_handler(int irq, void *d)
|
||||
outb(0x07, dev->iobase + 8); /* clears all flip-flops */
|
||||
#ifdef DEBUG
|
||||
printk("das6402: Got %i samples\n\n",
|
||||
devpriv->das6402_wordsread - diff);
|
||||
devpriv->das6402_wordsread - diff);
|
||||
#endif
|
||||
s->async->events |= COMEDI_CB_EOA;
|
||||
comedi_event(dev, s);
|
||||
@@ -196,7 +198,8 @@ static void das6402_ai_fifo_read(struct comedi_device *dev, short *data, int n)
|
||||
}
|
||||
#endif
|
||||
|
||||
static void das6402_ai_fifo_dregs(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
static void das6402_ai_fifo_dregs(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
while (1) {
|
||||
if (!(inb(dev->iobase + 8) & 0x01))
|
||||
@@ -205,7 +208,8 @@ static void das6402_ai_fifo_dregs(struct comedi_device *dev, struct comedi_subde
|
||||
}
|
||||
}
|
||||
|
||||
static int das6402_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
static int das6402_ai_cancel(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
/*
|
||||
* This function should reset the board from whatever condition it
|
||||
@@ -227,8 +231,8 @@ static int das6402_ai_cancel(struct comedi_device *dev, struct comedi_subdevice
|
||||
}
|
||||
|
||||
#ifdef unused
|
||||
static int das6402_ai_mode2(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
comedi_trig *it)
|
||||
static int das6402_ai_mode2(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, comedi_trig * it)
|
||||
{
|
||||
devpriv->das6402_ignoreirq = 1;
|
||||
|
||||
@@ -300,7 +304,8 @@ static int das6402_detach(struct comedi_device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int das6402_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
static int das6402_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it)
|
||||
{
|
||||
unsigned int irq;
|
||||
unsigned long iobase;
|
||||
|
||||
@@ -118,114 +118,114 @@ struct das800_board {
|
||||
static const struct comedi_lrange range_das800_ai = {
|
||||
1,
|
||||
{
|
||||
RANGE(-5, 5),
|
||||
}
|
||||
RANGE(-5, 5),
|
||||
}
|
||||
};
|
||||
|
||||
static const struct comedi_lrange range_das801_ai = {
|
||||
9,
|
||||
{
|
||||
RANGE(-5, 5),
|
||||
RANGE(-10, 10),
|
||||
RANGE(0, 10),
|
||||
RANGE(-0.5, 0.5),
|
||||
RANGE(0, 1),
|
||||
RANGE(-0.05, 0.05),
|
||||
RANGE(0, 0.1),
|
||||
RANGE(-0.01, 0.01),
|
||||
RANGE(0, 0.02),
|
||||
}
|
||||
RANGE(-5, 5),
|
||||
RANGE(-10, 10),
|
||||
RANGE(0, 10),
|
||||
RANGE(-0.5, 0.5),
|
||||
RANGE(0, 1),
|
||||
RANGE(-0.05, 0.05),
|
||||
RANGE(0, 0.1),
|
||||
RANGE(-0.01, 0.01),
|
||||
RANGE(0, 0.02),
|
||||
}
|
||||
};
|
||||
|
||||
static const struct comedi_lrange range_cio_das801_ai = {
|
||||
9,
|
||||
{
|
||||
RANGE(-5, 5),
|
||||
RANGE(-10, 10),
|
||||
RANGE(0, 10),
|
||||
RANGE(-0.5, 0.5),
|
||||
RANGE(0, 1),
|
||||
RANGE(-0.05, 0.05),
|
||||
RANGE(0, 0.1),
|
||||
RANGE(-0.005, 0.005),
|
||||
RANGE(0, 0.01),
|
||||
}
|
||||
RANGE(-5, 5),
|
||||
RANGE(-10, 10),
|
||||
RANGE(0, 10),
|
||||
RANGE(-0.5, 0.5),
|
||||
RANGE(0, 1),
|
||||
RANGE(-0.05, 0.05),
|
||||
RANGE(0, 0.1),
|
||||
RANGE(-0.005, 0.005),
|
||||
RANGE(0, 0.01),
|
||||
}
|
||||
};
|
||||
|
||||
static const struct comedi_lrange range_das802_ai = {
|
||||
9,
|
||||
{
|
||||
RANGE(-5, 5),
|
||||
RANGE(-10, 10),
|
||||
RANGE(0, 10),
|
||||
RANGE(-2.5, 2.5),
|
||||
RANGE(0, 5),
|
||||
RANGE(-1.25, 1.25),
|
||||
RANGE(0, 2.5),
|
||||
RANGE(-0.625, 0.625),
|
||||
RANGE(0, 1.25),
|
||||
}
|
||||
RANGE(-5, 5),
|
||||
RANGE(-10, 10),
|
||||
RANGE(0, 10),
|
||||
RANGE(-2.5, 2.5),
|
||||
RANGE(0, 5),
|
||||
RANGE(-1.25, 1.25),
|
||||
RANGE(0, 2.5),
|
||||
RANGE(-0.625, 0.625),
|
||||
RANGE(0, 1.25),
|
||||
}
|
||||
};
|
||||
|
||||
static const struct comedi_lrange range_das80216_ai = {
|
||||
8,
|
||||
{
|
||||
RANGE(-10, 10),
|
||||
RANGE(0, 10),
|
||||
RANGE(-5, 5),
|
||||
RANGE(0, 5),
|
||||
RANGE(-2.5, 2.5),
|
||||
RANGE(0, 2.5),
|
||||
RANGE(-1.25, 1.25),
|
||||
RANGE(0, 1.25),
|
||||
}
|
||||
RANGE(-10, 10),
|
||||
RANGE(0, 10),
|
||||
RANGE(-5, 5),
|
||||
RANGE(0, 5),
|
||||
RANGE(-2.5, 2.5),
|
||||
RANGE(0, 2.5),
|
||||
RANGE(-1.25, 1.25),
|
||||
RANGE(0, 1.25),
|
||||
}
|
||||
};
|
||||
|
||||
enum { das800, ciodas800, das801, ciodas801, das802, ciodas802, ciodas80216 };
|
||||
|
||||
static const struct das800_board das800_boards[] = {
|
||||
{
|
||||
.name = "das-800",
|
||||
.ai_speed = 25000,
|
||||
.ai_range = &range_das800_ai,
|
||||
.resolution = 12,
|
||||
},
|
||||
.name = "das-800",
|
||||
.ai_speed = 25000,
|
||||
.ai_range = &range_das800_ai,
|
||||
.resolution = 12,
|
||||
},
|
||||
{
|
||||
.name = "cio-das800",
|
||||
.ai_speed = 20000,
|
||||
.ai_range = &range_das800_ai,
|
||||
.resolution = 12,
|
||||
},
|
||||
.name = "cio-das800",
|
||||
.ai_speed = 20000,
|
||||
.ai_range = &range_das800_ai,
|
||||
.resolution = 12,
|
||||
},
|
||||
{
|
||||
.name = "das-801",
|
||||
.ai_speed = 25000,
|
||||
.ai_range = &range_das801_ai,
|
||||
.resolution = 12,
|
||||
},
|
||||
.name = "das-801",
|
||||
.ai_speed = 25000,
|
||||
.ai_range = &range_das801_ai,
|
||||
.resolution = 12,
|
||||
},
|
||||
{
|
||||
.name = "cio-das801",
|
||||
.ai_speed = 20000,
|
||||
.ai_range = &range_cio_das801_ai,
|
||||
.resolution = 12,
|
||||
},
|
||||
.name = "cio-das801",
|
||||
.ai_speed = 20000,
|
||||
.ai_range = &range_cio_das801_ai,
|
||||
.resolution = 12,
|
||||
},
|
||||
{
|
||||
.name = "das-802",
|
||||
.ai_speed = 25000,
|
||||
.ai_range = &range_das802_ai,
|
||||
.resolution = 12,
|
||||
},
|
||||
.name = "das-802",
|
||||
.ai_speed = 25000,
|
||||
.ai_range = &range_das802_ai,
|
||||
.resolution = 12,
|
||||
},
|
||||
{
|
||||
.name = "cio-das802",
|
||||
.ai_speed = 20000,
|
||||
.ai_range = &range_das802_ai,
|
||||
.resolution = 12,
|
||||
},
|
||||
.name = "cio-das802",
|
||||
.ai_speed = 20000,
|
||||
.ai_range = &range_das802_ai,
|
||||
.resolution = 12,
|
||||
},
|
||||
{
|
||||
.name = "cio-das802/16",
|
||||
.ai_speed = 10000,
|
||||
.ai_range = &range_das80216_ai,
|
||||
.resolution = 16,
|
||||
},
|
||||
.name = "cio-das802/16",
|
||||
.ai_speed = 10000,
|
||||
.ai_range = &range_das80216_ai,
|
||||
.resolution = 16,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -243,7 +243,8 @@ struct das800_private {
|
||||
|
||||
#define devpriv ((struct das800_private *)dev->private)
|
||||
|
||||
static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int das800_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int das800_detach(struct comedi_device *dev);
|
||||
static int das800_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
|
||||
|
||||
@@ -260,15 +261,20 @@ static struct comedi_driver driver_das800 = {
|
||||
static irqreturn_t das800_interrupt(int irq, void *d);
|
||||
static void enable_das800(struct comedi_device *dev);
|
||||
static void disable_das800(struct comedi_device *dev);
|
||||
static int das800_ai_do_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd);
|
||||
static int das800_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
|
||||
static int das800_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int das800_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int das800_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int das800_ai_do_cmdtest(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd);
|
||||
static int das800_ai_do_cmd(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s);
|
||||
static int das800_ai_rinsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
static int das800_di_rbits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
static int das800_do_wbits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
static int das800_probe(struct comedi_device *dev);
|
||||
static int das800_set_frequency(struct comedi_device *dev);
|
||||
|
||||
@@ -330,7 +336,7 @@ static int das800_probe(struct comedi_device *dev)
|
||||
break;
|
||||
default:
|
||||
printk(" Board model: probe returned 0x%x (unknown)\n",
|
||||
id_bits);
|
||||
id_bits);
|
||||
return board;
|
||||
break;
|
||||
}
|
||||
@@ -429,7 +435,7 @@ static irqreturn_t das800_interrupt(int irq, void *d)
|
||||
* We already have spinlock, so indirect addressing is safe */
|
||||
outb(CONTROL1, dev->iobase + DAS800_GAIN); /* select dev->iobase + 2 to be control register 1 */
|
||||
outb(CONTROL1_INTE | devpriv->do_bits,
|
||||
dev->iobase + DAS800_CONTROL1);
|
||||
dev->iobase + DAS800_CONTROL1);
|
||||
spin_unlock_irqrestore(&dev->spinlock, irq_flags);
|
||||
/* otherwise, stop taking data */
|
||||
} else {
|
||||
@@ -585,8 +591,9 @@ static void disable_das800(struct comedi_device *dev)
|
||||
spin_unlock_irqrestore(&dev->spinlock, irq_flags);
|
||||
}
|
||||
|
||||
static int das800_ai_do_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd)
|
||||
static int das800_ai_do_cmdtest(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd)
|
||||
{
|
||||
int err = 0;
|
||||
int tmp;
|
||||
@@ -676,8 +683,9 @@ static int das800_ai_do_cmdtest(struct comedi_device *dev, struct comedi_subdevi
|
||||
tmp = cmd->convert_arg;
|
||||
/* calculate counter values that give desired timing */
|
||||
i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1),
|
||||
&(devpriv->divisor2), &(cmd->convert_arg),
|
||||
cmd->flags & TRIG_ROUND_MASK);
|
||||
&(devpriv->divisor2),
|
||||
&(cmd->convert_arg),
|
||||
cmd->flags & TRIG_ROUND_MASK);
|
||||
if (tmp != cmd->convert_arg)
|
||||
err++;
|
||||
}
|
||||
@@ -691,14 +699,14 @@ static int das800_ai_do_cmdtest(struct comedi_device *dev, struct comedi_subdevi
|
||||
startChan = CR_CHAN(cmd->chanlist[0]);
|
||||
for (i = 1; i < cmd->chanlist_len; i++) {
|
||||
if (CR_CHAN(cmd->chanlist[i]) !=
|
||||
(startChan + i) % N_CHAN_AI) {
|
||||
(startChan + i) % N_CHAN_AI) {
|
||||
comedi_error(dev,
|
||||
"entries in chanlist must be consecutive channels, counting upwards\n");
|
||||
"entries in chanlist must be consecutive channels, counting upwards\n");
|
||||
err++;
|
||||
}
|
||||
if (CR_RANGE(cmd->chanlist[i]) != gain) {
|
||||
comedi_error(dev,
|
||||
"entries in chanlist must all have the same gain\n");
|
||||
"entries in chanlist must all have the same gain\n");
|
||||
err++;
|
||||
}
|
||||
}
|
||||
@@ -710,7 +718,8 @@ static int das800_ai_do_cmdtest(struct comedi_device *dev, struct comedi_subdevi
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int das800_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
static int das800_ai_do_cmd(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
int startChan, endChan, scan, gain;
|
||||
int conv_bits;
|
||||
@@ -719,7 +728,7 @@ static int das800_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *
|
||||
|
||||
if (!dev->irq) {
|
||||
comedi_error(dev,
|
||||
"no irq assigned for das-800, cannot do hardware conversions");
|
||||
"no irq assigned for das-800, cannot do hardware conversions");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -767,8 +776,10 @@ static int das800_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *
|
||||
conv_bits |= CASC | ITE;
|
||||
/* set conversion frequency */
|
||||
i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1),
|
||||
&(devpriv->divisor2), &(async->cmd.convert_arg),
|
||||
async->cmd.flags & TRIG_ROUND_MASK);
|
||||
&(devpriv->divisor2),
|
||||
&(async->cmd.convert_arg),
|
||||
async->cmd.
|
||||
flags & TRIG_ROUND_MASK);
|
||||
if (das800_set_frequency(dev) < 0) {
|
||||
comedi_error(dev, "Error setting up counters");
|
||||
return -1;
|
||||
@@ -789,8 +800,9 @@ static int das800_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int das800_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int das800_ai_rinsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
int i, n;
|
||||
int chan;
|
||||
@@ -843,8 +855,9 @@ static int das800_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s
|
||||
return n;
|
||||
}
|
||||
|
||||
static int das800_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int das800_di_rbits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
unsigned int bits;
|
||||
|
||||
@@ -856,8 +869,9 @@ static int das800_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int das800_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int das800_do_wbits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
int wbits;
|
||||
unsigned long irq_flags;
|
||||
|
||||
@@ -168,11 +168,11 @@ Configuration Options:
|
||||
static const struct comedi_lrange dmm32at_airanges = {
|
||||
4,
|
||||
{
|
||||
UNI_RANGE(10),
|
||||
UNI_RANGE(5),
|
||||
BIP_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
}
|
||||
UNI_RANGE(10),
|
||||
UNI_RANGE(5),
|
||||
BIP_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
}
|
||||
};
|
||||
|
||||
/* register values for above ranges */
|
||||
@@ -189,11 +189,11 @@ static const unsigned char dmm32at_rangebits[] = {
|
||||
static const struct comedi_lrange dmm32at_aoranges = {
|
||||
4,
|
||||
{
|
||||
UNI_RANGE(10),
|
||||
UNI_RANGE(5),
|
||||
BIP_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
}
|
||||
UNI_RANGE(10),
|
||||
UNI_RANGE(5),
|
||||
BIP_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -214,16 +214,16 @@ struct dmm32at_board {
|
||||
};
|
||||
static const struct dmm32at_board dmm32at_boards[] = {
|
||||
{
|
||||
.name = "dmm32at",
|
||||
.ai_chans = 32,
|
||||
.ai_bits = 16,
|
||||
.ai_ranges = &dmm32at_airanges,
|
||||
.ao_chans = 4,
|
||||
.ao_bits = 12,
|
||||
.ao_ranges = &dmm32at_aoranges,
|
||||
.have_dio = 1,
|
||||
.dio_chans = 24,
|
||||
},
|
||||
.name = "dmm32at",
|
||||
.ai_chans = 32,
|
||||
.ai_bits = 16,
|
||||
.ai_ranges = &dmm32at_airanges,
|
||||
.ao_chans = 4,
|
||||
.ao_bits = 12,
|
||||
.ao_ranges = &dmm32at_aoranges,
|
||||
.have_dio = 1,
|
||||
.dio_chans = 24,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -259,7 +259,8 @@ struct dmm32at_private {
|
||||
* the board, and also about the kernel module that contains
|
||||
* the device code.
|
||||
*/
|
||||
static int dmm32at_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int dmm32at_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int dmm32at_detach(struct comedi_device *dev);
|
||||
static struct comedi_driver driver_dmm32at = {
|
||||
.driver_name = "dmm32at",
|
||||
@@ -290,20 +291,29 @@ static struct comedi_driver driver_dmm32at = {
|
||||
};
|
||||
|
||||
/* prototypes for driver functions below */
|
||||
static int dmm32at_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int dmm32at_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int dmm32at_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int dmm32at_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int dmm32at_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int dmm32at_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd);
|
||||
static int dmm32at_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
|
||||
static int dmm32at_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
|
||||
static int dmm32at_ai_rinsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int dmm32at_ao_winsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int dmm32at_ao_rinsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int dmm32at_dio_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int dmm32at_dio_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
static int dmm32at_ai_cmdtest(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd);
|
||||
static int dmm32at_ai_cmd(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s);
|
||||
static int dmm32at_ai_cancel(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s);
|
||||
static int dmm32at_ns_to_timer(unsigned int *ns, int round);
|
||||
static irqreturn_t dmm32at_isr(int irq, void *d);
|
||||
void dmm32at_setaitimer(struct comedi_device *dev, unsigned int nansec);
|
||||
@@ -314,7 +324,8 @@ void dmm32at_setaitimer(struct comedi_device *dev, unsigned int nansec);
|
||||
* in the driver structure, dev->board_ptr contains that
|
||||
* address.
|
||||
*/
|
||||
static int dmm32at_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
static int dmm32at_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it)
|
||||
{
|
||||
int ret;
|
||||
struct comedi_subdevice *s;
|
||||
@@ -369,12 +380,12 @@ static int dmm32at_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
airback = dmm_inb(dev, DMM32AT_AIRBACK);
|
||||
|
||||
printk("dmm32at: lo=0x%02x hi=0x%02x fifostat=0x%02x\n",
|
||||
ailo, aihi, fifostat);
|
||||
ailo, aihi, fifostat);
|
||||
printk("dmm32at: aistat=0x%02x intstat=0x%02x airback=0x%02x\n",
|
||||
aistat, intstat, airback);
|
||||
aistat, intstat, airback);
|
||||
|
||||
if ((ailo != 0x00) || (aihi != 0x1f) || (fifostat != 0x80) ||
|
||||
(aistat != 0x60 || (intstat != 0x00) || airback != 0x0c)) {
|
||||
(aistat != 0x60 || (intstat != 0x00) || airback != 0x0c)) {
|
||||
printk("dmmat32: board detection failed\n");
|
||||
return -EIO;
|
||||
}
|
||||
@@ -450,7 +461,7 @@ static int dmm32at_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_DIOACC);
|
||||
/* set the DIO's to the defualt input setting */
|
||||
devpriv->dio_config = DMM32AT_DIRA | DMM32AT_DIRB |
|
||||
DMM32AT_DIRCL | DMM32AT_DIRCH | DMM32AT_DIENABLE;
|
||||
DMM32AT_DIRCL | DMM32AT_DIRCH | DMM32AT_DIENABLE;
|
||||
dmm_outb(dev, DMM32AT_DIOCONF, devpriv->dio_config);
|
||||
|
||||
/* set up the subdevice */
|
||||
@@ -497,8 +508,9 @@ static int dmm32at_detach(struct comedi_device *dev)
|
||||
* mode.
|
||||
*/
|
||||
|
||||
static int dmm32at_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int dmm32at_ai_rinsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int n, i;
|
||||
unsigned int d;
|
||||
@@ -568,8 +580,9 @@ static int dmm32at_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *
|
||||
return n;
|
||||
}
|
||||
|
||||
static int dmm32at_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd)
|
||||
static int dmm32at_ai_cmdtest(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd)
|
||||
{
|
||||
int err = 0;
|
||||
int tmp;
|
||||
@@ -618,7 +631,7 @@ static int dmm32at_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
|
||||
|
||||
/* note that mutual compatiblity is not an issue here */
|
||||
if (cmd->scan_begin_src != TRIG_TIMER &&
|
||||
cmd->scan_begin_src != TRIG_EXT)
|
||||
cmd->scan_begin_src != TRIG_EXT)
|
||||
err++;
|
||||
if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
|
||||
err++;
|
||||
@@ -703,21 +716,21 @@ static int dmm32at_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
|
||||
if (cmd->scan_begin_src == TRIG_TIMER) {
|
||||
tmp = cmd->scan_begin_arg;
|
||||
dmm32at_ns_to_timer(&cmd->scan_begin_arg,
|
||||
cmd->flags & TRIG_ROUND_MASK);
|
||||
cmd->flags & TRIG_ROUND_MASK);
|
||||
if (tmp != cmd->scan_begin_arg)
|
||||
err++;
|
||||
}
|
||||
if (cmd->convert_src == TRIG_TIMER) {
|
||||
tmp = cmd->convert_arg;
|
||||
dmm32at_ns_to_timer(&cmd->convert_arg,
|
||||
cmd->flags & TRIG_ROUND_MASK);
|
||||
cmd->flags & TRIG_ROUND_MASK);
|
||||
if (tmp != cmd->convert_arg)
|
||||
err++;
|
||||
if (cmd->scan_begin_src == TRIG_TIMER &&
|
||||
cmd->scan_begin_arg <
|
||||
cmd->convert_arg * cmd->scan_end_arg) {
|
||||
cmd->scan_begin_arg <
|
||||
cmd->convert_arg * cmd->scan_end_arg) {
|
||||
cmd->scan_begin_arg =
|
||||
cmd->convert_arg * cmd->scan_end_arg;
|
||||
cmd->convert_arg * cmd->scan_end_arg;
|
||||
err++;
|
||||
}
|
||||
}
|
||||
@@ -733,14 +746,14 @@ static int dmm32at_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
|
||||
start_chan = CR_CHAN(cmd->chanlist[0]);
|
||||
for (i = 1; i < cmd->chanlist_len; i++) {
|
||||
if (CR_CHAN(cmd->chanlist[i]) !=
|
||||
(start_chan + i) % s->n_chan) {
|
||||
(start_chan + i) % s->n_chan) {
|
||||
comedi_error(dev,
|
||||
"entries in chanlist must be consecutive channels, counting upwards\n");
|
||||
"entries in chanlist must be consecutive channels, counting upwards\n");
|
||||
err++;
|
||||
}
|
||||
if (CR_RANGE(cmd->chanlist[i]) != gain) {
|
||||
comedi_error(dev,
|
||||
"entries in chanlist must all have the same gain\n");
|
||||
"entries in chanlist must all have the same gain\n");
|
||||
err++;
|
||||
}
|
||||
}
|
||||
@@ -822,7 +835,8 @@ static int dmm32at_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
|
||||
}
|
||||
|
||||
static int dmm32at_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
static int dmm32at_ai_cancel(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
devpriv->ai_scans_left = 1;
|
||||
return 0;
|
||||
@@ -893,8 +907,9 @@ static int dmm32at_ns_to_timer(unsigned int *ns, int round)
|
||||
return *ns;
|
||||
}
|
||||
|
||||
static int dmm32at_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int dmm32at_ao_winsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int i;
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
@@ -936,8 +951,9 @@ static int dmm32at_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *
|
||||
|
||||
/* AO subdevices should have a read insn as well as a write insn.
|
||||
* Usually this means copying a value stored in devpriv. */
|
||||
static int dmm32at_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int dmm32at_ao_rinsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int i;
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
@@ -953,8 +969,9 @@ static int dmm32at_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *
|
||||
* useful to applications if you implement the insn_bits interface.
|
||||
* This allows packed reading/writing of the DIO channels. The
|
||||
* comedi core can convert between insn_bits and insn_read/write */
|
||||
static int dmm32at_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int dmm32at_dio_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
unsigned char diobits;
|
||||
|
||||
@@ -975,7 +992,7 @@ static int dmm32at_dio_insn_bits(struct comedi_device *dev, struct comedi_subdev
|
||||
|
||||
/* if either part of dio is set for output */
|
||||
if (((devpriv->dio_config & DMM32AT_DIRCL) == 0) ||
|
||||
((devpriv->dio_config & DMM32AT_DIRCH) == 0)) {
|
||||
((devpriv->dio_config & DMM32AT_DIRCH) == 0)) {
|
||||
diobits = (s->state & 0x00ff0000) >> 16;
|
||||
dmm_outb(dev, DMM32AT_DIOC, diobits);
|
||||
}
|
||||
@@ -1006,8 +1023,9 @@ static int dmm32at_dio_insn_bits(struct comedi_device *dev, struct comedi_subdev
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int dmm32at_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int dmm32at_dio_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
unsigned char chanbit;
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
|
||||
@@ -88,7 +88,8 @@ Configuration options:
|
||||
#define DT2801_STATUS 1
|
||||
#define DT2801_CMD 1
|
||||
|
||||
static int dt2801_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int dt2801_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int dt2801_detach(struct comedi_device *dev);
|
||||
static struct comedi_driver driver_dt2801 = {
|
||||
.driver_name = "dt2801",
|
||||
@@ -102,37 +103,57 @@ COMEDI_INITCLEANUP(driver_dt2801);
|
||||
#if 0
|
||||
/* ignore 'defined but not used' warning */
|
||||
static const struct comedi_lrange range_dt2801_ai_pgh_bipolar = { 4, {
|
||||
RANGE(-10, 10),
|
||||
RANGE(-5, 5),
|
||||
RANGE(-2.5, 2.5),
|
||||
RANGE(-1.25, 1.25),
|
||||
}
|
||||
RANGE(-10,
|
||||
10),
|
||||
RANGE(-5,
|
||||
5),
|
||||
RANGE
|
||||
(-2.5,
|
||||
2.5),
|
||||
RANGE
|
||||
(-1.25,
|
||||
1.25),
|
||||
}
|
||||
};
|
||||
#endif
|
||||
static const struct comedi_lrange range_dt2801_ai_pgl_bipolar = { 4, {
|
||||
RANGE(-10, 10),
|
||||
RANGE(-1, 1),
|
||||
RANGE(-0.1, 0.1),
|
||||
RANGE(-0.02, 0.02),
|
||||
}
|
||||
RANGE(-10,
|
||||
10),
|
||||
RANGE(-1,
|
||||
1),
|
||||
RANGE
|
||||
(-0.1,
|
||||
0.1),
|
||||
RANGE
|
||||
(-0.02,
|
||||
0.02),
|
||||
}
|
||||
};
|
||||
|
||||
#if 0
|
||||
/* ignore 'defined but not used' warning */
|
||||
static const struct comedi_lrange range_dt2801_ai_pgh_unipolar = { 4, {
|
||||
RANGE(0, 10),
|
||||
RANGE(0, 5),
|
||||
RANGE(0, 2.5),
|
||||
RANGE(0, 1.25),
|
||||
}
|
||||
RANGE(0,
|
||||
10),
|
||||
RANGE(0,
|
||||
5),
|
||||
RANGE(0,
|
||||
2.5),
|
||||
RANGE(0,
|
||||
1.25),
|
||||
}
|
||||
};
|
||||
#endif
|
||||
static const struct comedi_lrange range_dt2801_ai_pgl_unipolar = { 4, {
|
||||
RANGE(0, 10),
|
||||
RANGE(0, 1),
|
||||
RANGE(0, 0.1),
|
||||
RANGE(0, 0.02),
|
||||
}
|
||||
RANGE(0,
|
||||
10),
|
||||
RANGE(0,
|
||||
1),
|
||||
RANGE(0,
|
||||
0.1),
|
||||
RANGE(0,
|
||||
0.02),
|
||||
}
|
||||
};
|
||||
|
||||
struct dt2801_board {
|
||||
@@ -146,75 +167,74 @@ struct dt2801_board {
|
||||
int dabits;
|
||||
};
|
||||
|
||||
|
||||
/* Typeid's for the different boards of the DT2801-series
|
||||
(taken from the test-software, that comes with the board)
|
||||
*/
|
||||
static const struct dt2801_board boardtypes[] = {
|
||||
{
|
||||
.name = "dt2801",
|
||||
.boardcode = 0x09,
|
||||
.ad_diff = 2,
|
||||
.ad_chan = 16,
|
||||
.adbits = 12,
|
||||
.adrangetype = 0,
|
||||
.dabits = 12},
|
||||
.name = "dt2801",
|
||||
.boardcode = 0x09,
|
||||
.ad_diff = 2,
|
||||
.ad_chan = 16,
|
||||
.adbits = 12,
|
||||
.adrangetype = 0,
|
||||
.dabits = 12},
|
||||
{
|
||||
.name = "dt2801-a",
|
||||
.boardcode = 0x52,
|
||||
.ad_diff = 2,
|
||||
.ad_chan = 16,
|
||||
.adbits = 12,
|
||||
.adrangetype = 0,
|
||||
.dabits = 12},
|
||||
.name = "dt2801-a",
|
||||
.boardcode = 0x52,
|
||||
.ad_diff = 2,
|
||||
.ad_chan = 16,
|
||||
.adbits = 12,
|
||||
.adrangetype = 0,
|
||||
.dabits = 12},
|
||||
{
|
||||
.name = "dt2801/5716a",
|
||||
.boardcode = 0x82,
|
||||
.ad_diff = 1,
|
||||
.ad_chan = 16,
|
||||
.adbits = 16,
|
||||
.adrangetype = 1,
|
||||
.dabits = 12},
|
||||
.name = "dt2801/5716a",
|
||||
.boardcode = 0x82,
|
||||
.ad_diff = 1,
|
||||
.ad_chan = 16,
|
||||
.adbits = 16,
|
||||
.adrangetype = 1,
|
||||
.dabits = 12},
|
||||
{
|
||||
.name = "dt2805",
|
||||
.boardcode = 0x12,
|
||||
.ad_diff = 1,
|
||||
.ad_chan = 16,
|
||||
.adbits = 12,
|
||||
.adrangetype = 0,
|
||||
.dabits = 12},
|
||||
.name = "dt2805",
|
||||
.boardcode = 0x12,
|
||||
.ad_diff = 1,
|
||||
.ad_chan = 16,
|
||||
.adbits = 12,
|
||||
.adrangetype = 0,
|
||||
.dabits = 12},
|
||||
{
|
||||
.name = "dt2805/5716a",
|
||||
.boardcode = 0x92,
|
||||
.ad_diff = 1,
|
||||
.ad_chan = 16,
|
||||
.adbits = 16,
|
||||
.adrangetype = 1,
|
||||
.dabits = 12},
|
||||
.name = "dt2805/5716a",
|
||||
.boardcode = 0x92,
|
||||
.ad_diff = 1,
|
||||
.ad_chan = 16,
|
||||
.adbits = 16,
|
||||
.adrangetype = 1,
|
||||
.dabits = 12},
|
||||
{
|
||||
.name = "dt2808",
|
||||
.boardcode = 0x20,
|
||||
.ad_diff = 0,
|
||||
.ad_chan = 16,
|
||||
.adbits = 12,
|
||||
.adrangetype = 2,
|
||||
.dabits = 8},
|
||||
.name = "dt2808",
|
||||
.boardcode = 0x20,
|
||||
.ad_diff = 0,
|
||||
.ad_chan = 16,
|
||||
.adbits = 12,
|
||||
.adrangetype = 2,
|
||||
.dabits = 8},
|
||||
{
|
||||
.name = "dt2818",
|
||||
.boardcode = 0xa2,
|
||||
.ad_diff = 0,
|
||||
.ad_chan = 4,
|
||||
.adbits = 12,
|
||||
.adrangetype = 0,
|
||||
.dabits = 12},
|
||||
.name = "dt2818",
|
||||
.boardcode = 0xa2,
|
||||
.ad_diff = 0,
|
||||
.ad_chan = 4,
|
||||
.adbits = 12,
|
||||
.adrangetype = 0,
|
||||
.dabits = 12},
|
||||
{
|
||||
.name = "dt2809",
|
||||
.boardcode = 0xb0,
|
||||
.ad_diff = 0,
|
||||
.ad_chan = 8,
|
||||
.adbits = 12,
|
||||
.adrangetype = 1,
|
||||
.dabits = 12},
|
||||
.name = "dt2809",
|
||||
.boardcode = 0xb0,
|
||||
.ad_diff = 0,
|
||||
.ad_chan = 8,
|
||||
.adbits = 12,
|
||||
.adrangetype = 1,
|
||||
.dabits = 12},
|
||||
};
|
||||
|
||||
#define boardtype (*(const struct dt2801_board *)dev->board_ptr)
|
||||
@@ -227,16 +247,21 @@ struct dt2801_private {
|
||||
|
||||
#define devpriv ((struct dt2801_private *)dev->private)
|
||||
|
||||
static int dt2801_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int dt2801_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int dt2801_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int dt2801_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int dt2801_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int dt2801_ai_insn_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int dt2801_ao_insn_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int dt2801_ao_insn_write(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int dt2801_dio_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int dt2801_dio_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
/* These are the low-level routines:
|
||||
writecommand: write a command to the board
|
||||
@@ -299,7 +324,8 @@ static int dt2801_writedata(struct comedi_device *dev, unsigned int data)
|
||||
}
|
||||
#if 0
|
||||
if (stat & DT_S_READY) {
|
||||
printk("dt2801: ready flag set (bad!) in dt2801_writedata()\n");
|
||||
printk
|
||||
("dt2801: ready flag set (bad!) in dt2801_writedata()\n");
|
||||
return -EIO;
|
||||
}
|
||||
#endif
|
||||
@@ -353,7 +379,8 @@ static int dt2801_writecmd(struct comedi_device *dev, int command)
|
||||
|
||||
stat = inb_p(dev->iobase + DT2801_STATUS);
|
||||
if (stat & DT_S_COMPOSITE_ERROR) {
|
||||
printk("dt2801: composite-error in dt2801_writecmd(), ignoring\n");
|
||||
printk
|
||||
("dt2801: composite-error in dt2801_writecmd(), ignoring\n");
|
||||
}
|
||||
if (!(stat & DT_S_READY)) {
|
||||
printk("dt2801: !ready in dt2801_writecmd(), ignoring\n");
|
||||
@@ -463,8 +490,8 @@ static const struct comedi_lrange *ai_range_lkup(int type, int opt)
|
||||
switch (type) {
|
||||
case 0:
|
||||
return (opt) ?
|
||||
&range_dt2801_ai_pgl_unipolar :
|
||||
&range_dt2801_ai_pgl_bipolar;
|
||||
&range_dt2801_ai_pgl_unipolar :
|
||||
&range_dt2801_ai_pgl_bipolar;
|
||||
case 1:
|
||||
return (opt) ? &range_unipolar10 : &range_bipolar10;
|
||||
case 2:
|
||||
@@ -510,10 +537,10 @@ static int dt2801_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
goto havetype;
|
||||
}
|
||||
printk("dt2801: unrecognized board code=0x%02x, contact author\n",
|
||||
board_code);
|
||||
board_code);
|
||||
type = 0;
|
||||
|
||||
havetype:
|
||||
havetype:
|
||||
dev->board_ptr = boardtypes + type;
|
||||
printk("dt2801: %s at port 0x%lx", boardtype.name, iobase);
|
||||
|
||||
@@ -579,7 +606,7 @@ static int dt2801_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
s->insn_config = dt2801_dio_insn_config;
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
out:
|
||||
printk("\n");
|
||||
|
||||
return ret;
|
||||
@@ -611,8 +638,9 @@ static int dt2801_error(struct comedi_device *dev, int stat)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static int dt2801_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int dt2801_ai_insn_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int d;
|
||||
int stat;
|
||||
@@ -633,16 +661,18 @@ static int dt2801_ai_insn_read(struct comedi_device *dev, struct comedi_subdevic
|
||||
return i;
|
||||
}
|
||||
|
||||
static int dt2801_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int dt2801_ao_insn_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
data[0] = devpriv->ao_readback[CR_CHAN(insn->chanspec)];
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dt2801_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int dt2801_ao_insn_write(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
dt2801_writecmd(dev, DT_C_WRITE_DAIM);
|
||||
dt2801_writedata(dev, CR_CHAN(insn->chanspec));
|
||||
@@ -653,8 +683,9 @@ static int dt2801_ao_insn_write(struct comedi_device *dev, struct comedi_subdevi
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dt2801_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int dt2801_dio_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int which = 0;
|
||||
|
||||
@@ -677,8 +708,9 @@ static int dt2801_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevi
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int dt2801_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int dt2801_dio_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int which = 0;
|
||||
|
||||
|
||||
@@ -53,46 +53,95 @@ Configuration options:
|
||||
static const char *driver_name = "dt2811";
|
||||
|
||||
static const struct comedi_lrange range_dt2811_pgh_ai_5_unipolar = { 4, {
|
||||
RANGE(0, 5),
|
||||
RANGE(0, 2.5),
|
||||
RANGE(0, 1.25),
|
||||
RANGE(0, 0.625)
|
||||
}
|
||||
RANGE
|
||||
(0, 5),
|
||||
RANGE
|
||||
(0,
|
||||
2.5),
|
||||
RANGE
|
||||
(0,
|
||||
1.25),
|
||||
RANGE
|
||||
(0,
|
||||
0.625)
|
||||
}
|
||||
};
|
||||
|
||||
static const struct comedi_lrange range_dt2811_pgh_ai_2_5_bipolar = { 4, {
|
||||
RANGE(-2.5, 2.5),
|
||||
RANGE(-1.25, 1.25),
|
||||
RANGE(-0.625, 0.625),
|
||||
RANGE(-0.3125, 0.3125)
|
||||
}
|
||||
RANGE
|
||||
(-2.5,
|
||||
2.5),
|
||||
RANGE
|
||||
(-1.25,
|
||||
1.25),
|
||||
RANGE
|
||||
(-0.625,
|
||||
0.625),
|
||||
RANGE
|
||||
(-0.3125,
|
||||
0.3125)
|
||||
}
|
||||
};
|
||||
|
||||
static const struct comedi_lrange range_dt2811_pgh_ai_5_bipolar = { 4, {
|
||||
RANGE(-5, 5),
|
||||
RANGE(-2.5, 2.5),
|
||||
RANGE(-1.25, 1.25),
|
||||
RANGE(-0.625, 0.625)
|
||||
}
|
||||
RANGE
|
||||
(-5, 5),
|
||||
RANGE
|
||||
(-2.5,
|
||||
2.5),
|
||||
RANGE
|
||||
(-1.25,
|
||||
1.25),
|
||||
RANGE
|
||||
(-0.625,
|
||||
0.625)
|
||||
}
|
||||
};
|
||||
|
||||
static const struct comedi_lrange range_dt2811_pgl_ai_5_unipolar = { 4, {
|
||||
RANGE(0, 5),
|
||||
RANGE(0, 0.5),
|
||||
RANGE(0, 0.05),
|
||||
RANGE(0, 0.01)
|
||||
}
|
||||
RANGE
|
||||
(0, 5),
|
||||
RANGE
|
||||
(0,
|
||||
0.5),
|
||||
RANGE
|
||||
(0,
|
||||
0.05),
|
||||
RANGE
|
||||
(0,
|
||||
0.01)
|
||||
}
|
||||
};
|
||||
|
||||
static const struct comedi_lrange range_dt2811_pgl_ai_2_5_bipolar = { 4, {
|
||||
RANGE(-2.5, 2.5),
|
||||
RANGE(-0.25, 0.25),
|
||||
RANGE(-0.025, 0.025),
|
||||
RANGE(-0.005, 0.005)
|
||||
}
|
||||
RANGE
|
||||
(-2.5,
|
||||
2.5),
|
||||
RANGE
|
||||
(-0.25,
|
||||
0.25),
|
||||
RANGE
|
||||
(-0.025,
|
||||
0.025),
|
||||
RANGE
|
||||
(-0.005,
|
||||
0.005)
|
||||
}
|
||||
};
|
||||
|
||||
static const struct comedi_lrange range_dt2811_pgl_ai_5_bipolar = { 4, {
|
||||
RANGE(-5, 5),
|
||||
RANGE(-0.5, 0.5),
|
||||
RANGE(-0.05, 0.05),
|
||||
RANGE(-0.01, 0.01)
|
||||
}
|
||||
RANGE
|
||||
(-5, 5),
|
||||
RANGE
|
||||
(-0.5,
|
||||
0.5),
|
||||
RANGE
|
||||
(-0.05,
|
||||
0.05),
|
||||
RANGE
|
||||
(-0.01,
|
||||
0.01)
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -202,20 +251,21 @@ struct dt2811_board {
|
||||
|
||||
static const struct dt2811_board boardtypes[] = {
|
||||
{"dt2811-pgh",
|
||||
&range_dt2811_pgh_ai_5_bipolar,
|
||||
&range_dt2811_pgh_ai_2_5_bipolar,
|
||||
&range_dt2811_pgh_ai_5_unipolar,
|
||||
},
|
||||
&range_dt2811_pgh_ai_5_bipolar,
|
||||
&range_dt2811_pgh_ai_2_5_bipolar,
|
||||
&range_dt2811_pgh_ai_5_unipolar,
|
||||
},
|
||||
{"dt2811-pgl",
|
||||
&range_dt2811_pgl_ai_5_bipolar,
|
||||
&range_dt2811_pgl_ai_2_5_bipolar,
|
||||
&range_dt2811_pgl_ai_5_unipolar,
|
||||
},
|
||||
&range_dt2811_pgl_ai_5_bipolar,
|
||||
&range_dt2811_pgl_ai_2_5_bipolar,
|
||||
&range_dt2811_pgl_ai_5_unipolar,
|
||||
},
|
||||
};
|
||||
|
||||
#define this_board ((const struct dt2811_board *)dev->board_ptr)
|
||||
|
||||
static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int dt2811_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int dt2811_detach(struct comedi_device *dev);
|
||||
static struct comedi_driver driver_dt2811 = {
|
||||
.driver_name = "dt2811",
|
||||
@@ -230,15 +280,18 @@ static struct comedi_driver driver_dt2811 = {
|
||||
COMEDI_INITCLEANUP(driver_dt2811);
|
||||
|
||||
static int dt2811_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int dt2811_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int dt2811_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int dt2811_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int dt2811_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int dt2811_ao_insn_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int dt2811_di_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int dt2811_do_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
enum { card_2811_pgh, card_2811_pgl };
|
||||
|
||||
@@ -349,7 +402,7 @@ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
irqs = probe_irq_on();
|
||||
|
||||
outb(DT2811_CLRERROR | DT2811_INTENB,
|
||||
dev->iobase + DT2811_ADCSR);
|
||||
dev->iobase + DT2811_ADCSR);
|
||||
outb(0, dev->iobase + DT2811_ADGCR);
|
||||
|
||||
udelay(100);
|
||||
@@ -368,7 +421,7 @@ static int dt2811_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
i = inb(dev->iobase + DT2811_ADDATHI);
|
||||
printk("(irq = %d)\n", irq);
|
||||
ret = request_irq(irq, dt2811_interrupt, 0,
|
||||
driver_name, dev);
|
||||
driver_name, dev);
|
||||
if (ret < 0)
|
||||
return -EIO;
|
||||
dev->irq = irq;
|
||||
@@ -500,7 +553,7 @@ static int dt2811_detach(struct comedi_device *dev)
|
||||
}
|
||||
|
||||
static int dt2811_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
int timeout = DT2811_TIMEOUT;
|
||||
@@ -510,7 +563,7 @@ static int dt2811_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
outb(chan, dev->iobase + DT2811_ADGCR);
|
||||
|
||||
while (timeout
|
||||
&& inb(dev->iobase + DT2811_ADCSR) & DT2811_ADBUSY)
|
||||
&& inb(dev->iobase + DT2811_ADCSR) & DT2811_ADBUSY)
|
||||
timeout--;
|
||||
if (!timeout)
|
||||
return -ETIME;
|
||||
@@ -526,7 +579,7 @@ static int dt2811_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
#if 0
|
||||
/* Wow. This is code from the Comedi stone age. But it hasn't been
|
||||
* replaced, so I'll let it stay. */
|
||||
int dt2811_adtrig(kdev_t minor, comedi_adtrig *adtrig)
|
||||
int dt2811_adtrig(kdev_t minor, comedi_adtrig * adtrig)
|
||||
{
|
||||
struct comedi_device *dev = comedi_devices + minor;
|
||||
|
||||
@@ -537,7 +590,7 @@ int dt2811_adtrig(kdev_t minor, comedi_adtrig *adtrig)
|
||||
case COMEDI_MDEMAND:
|
||||
dev->ntrig = adtrig->n - 1;
|
||||
/*printk("dt2811: AD soft trigger\n"); */
|
||||
/*outb(DT2811_CLRERROR|DT2811_INTENB,dev->iobase+DT2811_ADCSR); */ /* not neccessary */
|
||||
/*outb(DT2811_CLRERROR|DT2811_INTENB,dev->iobase+DT2811_ADCSR); *//* not neccessary */
|
||||
outb(dev->curadchan, dev->iobase + DT2811_ADGCR);
|
||||
do_gettimeofday(&trigtime);
|
||||
break;
|
||||
@@ -551,7 +604,7 @@ int dt2811_adtrig(kdev_t minor, comedi_adtrig *adtrig)
|
||||
#endif
|
||||
|
||||
static int dt2811_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int i;
|
||||
int chan;
|
||||
@@ -561,15 +614,16 @@ static int dt2811_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
for (i = 0; i < insn->n; i++) {
|
||||
outb(data[i] & 0xff, dev->iobase + DT2811_DADAT0LO + 2 * chan);
|
||||
outb((data[i] >> 8) & 0xff,
|
||||
dev->iobase + DT2811_DADAT0HI + 2 * chan);
|
||||
dev->iobase + DT2811_DADAT0HI + 2 * chan);
|
||||
devpriv->ao_readback[chan] = data[i];
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static int dt2811_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int dt2811_ao_insn_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int i;
|
||||
int chan;
|
||||
@@ -583,8 +637,9 @@ static int dt2811_ao_insn_read(struct comedi_device *dev, struct comedi_subdevic
|
||||
return i;
|
||||
}
|
||||
|
||||
static int dt2811_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int dt2811_di_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
if (insn->n != 2)
|
||||
return -EINVAL;
|
||||
@@ -594,8 +649,9 @@ static int dt2811_di_insn_bits(struct comedi_device *dev, struct comedi_subdevic
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int dt2811_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int dt2811_do_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
if (insn->n != 2)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -60,7 +60,8 @@ addition, the clock does not seem to be very accurate.
|
||||
#define DT2814_ENB 0x10
|
||||
#define DT2814_CHANMASK 0x0f
|
||||
|
||||
static int dt2814_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int dt2814_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int dt2814_detach(struct comedi_device *dev);
|
||||
static struct comedi_driver driver_dt2814 = {
|
||||
.driver_name = "dt2814",
|
||||
@@ -84,8 +85,9 @@ struct dt2814_private {
|
||||
#define DT2814_TIMEOUT 10
|
||||
#define DT2814_MAX_SPEED 100000 /* Arbitrary 10 khz limit */
|
||||
|
||||
static int dt2814_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int dt2814_ai_insn_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int n, i, hi, lo;
|
||||
int chan;
|
||||
@@ -135,8 +137,8 @@ static int dt2814_ns_to_timer(unsigned int *ns, unsigned int flags)
|
||||
return i;
|
||||
}
|
||||
|
||||
static int dt2814_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd)
|
||||
static int dt2814_ai_cmdtest(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_cmd *cmd)
|
||||
{
|
||||
int err = 0;
|
||||
int tmp;
|
||||
@@ -234,8 +236,8 @@ static int dt2814_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
int trigvar;
|
||||
|
||||
trigvar =
|
||||
dt2814_ns_to_timer(&cmd->scan_begin_arg,
|
||||
cmd->flags & TRIG_ROUND_MASK);
|
||||
dt2814_ns_to_timer(&cmd->scan_begin_arg,
|
||||
cmd->flags & TRIG_ROUND_MASK);
|
||||
|
||||
chan = CR_CHAN(cmd->chanlist[0]);
|
||||
|
||||
|
||||
@@ -62,12 +62,15 @@ Configuration options:
|
||||
#include <linux/delay.h>
|
||||
|
||||
static const struct comedi_lrange range_dt2815_ao_32_current = { 1, {
|
||||
RANGE_mA(0, 32)
|
||||
}
|
||||
RANGE_mA(0,
|
||||
32)
|
||||
}
|
||||
};
|
||||
|
||||
static const struct comedi_lrange range_dt2815_ao_20_current = { 1, {
|
||||
RANGE_mA(4, 20)
|
||||
}
|
||||
RANGE_mA(4,
|
||||
20)
|
||||
}
|
||||
};
|
||||
|
||||
#define DT2815_SIZE 2
|
||||
@@ -75,7 +78,8 @@ static const struct comedi_lrange range_dt2815_ao_20_current = { 1, {
|
||||
#define DT2815_DATA 0
|
||||
#define DT2815_STATUS 1
|
||||
|
||||
static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int dt2815_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int dt2815_detach(struct comedi_device *dev);
|
||||
static struct comedi_driver driver_dt2815 = {
|
||||
.driver_name = "dt2815",
|
||||
@@ -94,7 +98,6 @@ struct dt2815_private {
|
||||
unsigned int ao_readback[8];
|
||||
};
|
||||
|
||||
|
||||
#define devpriv ((struct dt2815_private *)dev->private)
|
||||
|
||||
static int dt2815_wait_for_status(struct comedi_device *dev, int status)
|
||||
@@ -108,8 +111,9 @@ static int dt2815_wait_for_status(struct comedi_device *dev, int status)
|
||||
return status;
|
||||
}
|
||||
|
||||
static int dt2815_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int dt2815_ao_insn_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int i;
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
@@ -122,7 +126,7 @@ static int dt2815_ao_insn_read(struct comedi_device *dev, struct comedi_subdevic
|
||||
}
|
||||
|
||||
static int dt2815_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int i;
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
@@ -136,8 +140,8 @@ static int dt2815_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
status = dt2815_wait_for_status(dev, 0x00);
|
||||
if (status != 0) {
|
||||
printk
|
||||
("dt2815: failed to write low byte on %d reason %x\n",
|
||||
chan, status);
|
||||
("dt2815: failed to write low byte on %d reason %x\n",
|
||||
chan, status);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
@@ -146,8 +150,8 @@ static int dt2815_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
status = dt2815_wait_for_status(dev, 0x10);
|
||||
if (status != 0x10) {
|
||||
printk
|
||||
("dt2815: failed to write high byte on %d reason %x\n",
|
||||
chan, status);
|
||||
("dt2815: failed to write high byte on %d reason %x\n",
|
||||
chan, status);
|
||||
return -EBUSY;
|
||||
}
|
||||
devpriv->ao_readback[chan] = data[i];
|
||||
@@ -212,12 +216,12 @@ static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
s->range_table_list = devpriv->range_type_list;
|
||||
|
||||
current_range_type = (it->options[3])
|
||||
? &range_dt2815_ao_20_current : &range_dt2815_ao_32_current;
|
||||
? &range_dt2815_ao_20_current : &range_dt2815_ao_32_current;
|
||||
voltage_range_type = (it->options[2])
|
||||
? &range_bipolar5 : &range_unipolar5;
|
||||
? &range_bipolar5 : &range_unipolar5;
|
||||
for (i = 0; i < 8; i++) {
|
||||
devpriv->range_type_list[i] = (it->options[5 + i])
|
||||
? current_range_type : voltage_range_type;
|
||||
? current_range_type : voltage_range_type;
|
||||
}
|
||||
|
||||
/* Init the 2815 */
|
||||
@@ -236,7 +240,7 @@ static int dt2815_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
break;
|
||||
} else if (status != 0x00) {
|
||||
printk("dt2815: unexpected status 0x%x (@t=%d)\n",
|
||||
status, i);
|
||||
status, i);
|
||||
if (status & 0x60) {
|
||||
outb(0x00, dev->iobase + DT2815_STATUS);
|
||||
}
|
||||
|
||||
@@ -47,7 +47,8 @@ Configuration options:
|
||||
#define DT2817_CR 0
|
||||
#define DT2817_DATA 1
|
||||
|
||||
static int dt2817_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int dt2817_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int dt2817_detach(struct comedi_device *dev);
|
||||
static struct comedi_driver driver_dt2817 = {
|
||||
.driver_name = "dt2817",
|
||||
@@ -58,8 +59,9 @@ static struct comedi_driver driver_dt2817 = {
|
||||
|
||||
COMEDI_INITCLEANUP(driver_dt2817);
|
||||
|
||||
static int dt2817_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int dt2817_dio_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int mask;
|
||||
int chan;
|
||||
@@ -96,8 +98,9 @@ static int dt2817_dio_insn_config(struct comedi_device *dev, struct comedi_subde
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dt2817_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int dt2817_dio_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
unsigned int changed;
|
||||
|
||||
@@ -115,13 +118,13 @@ static int dt2817_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevi
|
||||
outb(s->state & 0xff, dev->iobase + DT2817_DATA + 0);
|
||||
if (changed & 0x0000ff00)
|
||||
outb((s->state >> 8) & 0xff,
|
||||
dev->iobase + DT2817_DATA + 1);
|
||||
dev->iobase + DT2817_DATA + 1);
|
||||
if (changed & 0x00ff0000)
|
||||
outb((s->state >> 16) & 0xff,
|
||||
dev->iobase + DT2817_DATA + 2);
|
||||
dev->iobase + DT2817_DATA + 2);
|
||||
if (changed & 0xff000000)
|
||||
outb((s->state >> 24) & 0xff,
|
||||
dev->iobase + DT2817_DATA + 3);
|
||||
dev->iobase + DT2817_DATA + 3);
|
||||
}
|
||||
data[1] = inb(dev->iobase + DT2817_DATA + 0);
|
||||
data[1] |= (inb(dev->iobase + DT2817_DATA + 1) << 8);
|
||||
|
||||
@@ -155,46 +155,78 @@ Configuration options:
|
||||
#define DT2821_BDINIT 0x0001 /* (W) initialize board */
|
||||
|
||||
static const struct comedi_lrange range_dt282x_ai_lo_bipolar = { 4, {
|
||||
RANGE(-10, 10),
|
||||
RANGE(-5, 5),
|
||||
RANGE(-2.5, 2.5),
|
||||
RANGE(-1.25, 1.25)
|
||||
}
|
||||
RANGE(-10,
|
||||
10),
|
||||
RANGE(-5,
|
||||
5),
|
||||
RANGE(-2.5,
|
||||
2.5),
|
||||
RANGE
|
||||
(-1.25,
|
||||
1.25)
|
||||
}
|
||||
};
|
||||
|
||||
static const struct comedi_lrange range_dt282x_ai_lo_unipolar = { 4, {
|
||||
RANGE(0, 10),
|
||||
RANGE(0, 5),
|
||||
RANGE(0, 2.5),
|
||||
RANGE(0, 1.25)
|
||||
}
|
||||
RANGE(0,
|
||||
10),
|
||||
RANGE(0,
|
||||
5),
|
||||
RANGE(0,
|
||||
2.5),
|
||||
RANGE(0,
|
||||
1.25)
|
||||
}
|
||||
};
|
||||
|
||||
static const struct comedi_lrange range_dt282x_ai_5_bipolar = { 4, {
|
||||
RANGE(-5, 5),
|
||||
RANGE(-2.5, 2.5),
|
||||
RANGE(-1.25, 1.25),
|
||||
RANGE(-0.625, 0.625),
|
||||
}
|
||||
RANGE(-5,
|
||||
5),
|
||||
RANGE(-2.5,
|
||||
2.5),
|
||||
RANGE(-1.25,
|
||||
1.25),
|
||||
RANGE
|
||||
(-0.625,
|
||||
0.625),
|
||||
}
|
||||
};
|
||||
|
||||
static const struct comedi_lrange range_dt282x_ai_5_unipolar = { 4, {
|
||||
RANGE(0, 5),
|
||||
RANGE(0, 2.5),
|
||||
RANGE(0, 1.25),
|
||||
RANGE(0, 0.625),
|
||||
}
|
||||
RANGE(0,
|
||||
5),
|
||||
RANGE(0,
|
||||
2.5),
|
||||
RANGE(0,
|
||||
1.25),
|
||||
RANGE(0,
|
||||
0.625),
|
||||
}
|
||||
};
|
||||
|
||||
static const struct comedi_lrange range_dt282x_ai_hi_bipolar = { 4, {
|
||||
RANGE(-10, 10),
|
||||
RANGE(-1, 1),
|
||||
RANGE(-0.1, 0.1),
|
||||
RANGE(-0.02, 0.02)
|
||||
}
|
||||
RANGE(-10,
|
||||
10),
|
||||
RANGE(-1,
|
||||
1),
|
||||
RANGE(-0.1,
|
||||
0.1),
|
||||
RANGE
|
||||
(-0.02,
|
||||
0.02)
|
||||
}
|
||||
};
|
||||
|
||||
static const struct comedi_lrange range_dt282x_ai_hi_unipolar = { 4, {
|
||||
RANGE(0, 10),
|
||||
RANGE(0, 1),
|
||||
RANGE(0, 0.1),
|
||||
RANGE(0, 0.02)
|
||||
}
|
||||
RANGE(0,
|
||||
10),
|
||||
RANGE(0,
|
||||
1),
|
||||
RANGE(0,
|
||||
0.1),
|
||||
RANGE(0,
|
||||
0.02)
|
||||
}
|
||||
};
|
||||
|
||||
struct dt282x_board {
|
||||
@@ -217,7 +249,7 @@ static const struct dt282x_board boardtypes[] = {
|
||||
.ispgl = 0,
|
||||
.dachan = 2,
|
||||
.dabits = 12,
|
||||
},
|
||||
},
|
||||
{.name = "dt2821-f",
|
||||
.adbits = 12,
|
||||
.adchan_se = 16,
|
||||
@@ -226,7 +258,7 @@ static const struct dt282x_board boardtypes[] = {
|
||||
.ispgl = 0,
|
||||
.dachan = 2,
|
||||
.dabits = 12,
|
||||
},
|
||||
},
|
||||
{.name = "dt2821-g",
|
||||
.adbits = 12,
|
||||
.adchan_se = 16,
|
||||
@@ -235,7 +267,7 @@ static const struct dt282x_board boardtypes[] = {
|
||||
.ispgl = 0,
|
||||
.dachan = 2,
|
||||
.dabits = 12,
|
||||
},
|
||||
},
|
||||
{.name = "dt2823",
|
||||
.adbits = 16,
|
||||
.adchan_se = 0,
|
||||
@@ -244,16 +276,16 @@ static const struct dt282x_board boardtypes[] = {
|
||||
.ispgl = 0,
|
||||
.dachan = 2,
|
||||
.dabits = 16,
|
||||
},
|
||||
},
|
||||
{.name = "dt2824-pgh",
|
||||
.adbits = 12,
|
||||
.adchan_se = 16,
|
||||
.adchan_di = 8,
|
||||
.ai_speed = 20000,
|
||||
.ispgl = 0,
|
||||
.dachan = 0,
|
||||
.dabits = 0,
|
||||
},
|
||||
.adbits = 12,
|
||||
.adchan_se = 16,
|
||||
.adchan_di = 8,
|
||||
.ai_speed = 20000,
|
||||
.ispgl = 0,
|
||||
.dachan = 0,
|
||||
.dabits = 0,
|
||||
},
|
||||
{.name = "dt2824-pgl",
|
||||
.adbits = 12,
|
||||
.adchan_se = 16,
|
||||
@@ -262,7 +294,7 @@ static const struct dt282x_board boardtypes[] = {
|
||||
.ispgl = 1,
|
||||
.dachan = 0,
|
||||
.dabits = 0,
|
||||
},
|
||||
},
|
||||
{.name = "dt2825",
|
||||
.adbits = 12,
|
||||
.adchan_se = 16,
|
||||
@@ -271,7 +303,7 @@ static const struct dt282x_board boardtypes[] = {
|
||||
.ispgl = 1,
|
||||
.dachan = 2,
|
||||
.dabits = 12,
|
||||
},
|
||||
},
|
||||
{.name = "dt2827",
|
||||
.adbits = 16,
|
||||
.adchan_se = 0,
|
||||
@@ -280,7 +312,7 @@ static const struct dt282x_board boardtypes[] = {
|
||||
.ispgl = 0,
|
||||
.dachan = 2,
|
||||
.dabits = 12,
|
||||
},
|
||||
},
|
||||
{.name = "dt2828",
|
||||
.adbits = 12,
|
||||
.adchan_se = 4,
|
||||
@@ -289,7 +321,7 @@ static const struct dt282x_board boardtypes[] = {
|
||||
.ispgl = 0,
|
||||
.dachan = 2,
|
||||
.dabits = 12,
|
||||
},
|
||||
},
|
||||
{.name = "dt2829",
|
||||
.adbits = 16,
|
||||
.adchan_se = 8,
|
||||
@@ -298,7 +330,7 @@ static const struct dt282x_board boardtypes[] = {
|
||||
.ispgl = 0,
|
||||
.dachan = 2,
|
||||
.dabits = 16,
|
||||
},
|
||||
},
|
||||
{.name = "dt21-ez",
|
||||
.adbits = 12,
|
||||
.adchan_se = 16,
|
||||
@@ -307,7 +339,7 @@ static const struct dt282x_board boardtypes[] = {
|
||||
.ispgl = 0,
|
||||
.dachan = 2,
|
||||
.dabits = 12,
|
||||
},
|
||||
},
|
||||
{.name = "dt23-ez",
|
||||
.adbits = 16,
|
||||
.adchan_se = 16,
|
||||
@@ -316,7 +348,7 @@ static const struct dt282x_board boardtypes[] = {
|
||||
.ispgl = 0,
|
||||
.dachan = 0,
|
||||
.dabits = 0,
|
||||
},
|
||||
},
|
||||
{.name = "dt24-ez",
|
||||
.adbits = 12,
|
||||
.adchan_se = 16,
|
||||
@@ -325,7 +357,7 @@ static const struct dt282x_board boardtypes[] = {
|
||||
.ispgl = 0,
|
||||
.dachan = 0,
|
||||
.dabits = 0,
|
||||
},
|
||||
},
|
||||
{.name = "dt24-ez-pgl",
|
||||
.adbits = 12,
|
||||
.adchan_se = 16,
|
||||
@@ -334,7 +366,7 @@ static const struct dt282x_board boardtypes[] = {
|
||||
.ispgl = 1,
|
||||
.dachan = 0,
|
||||
.dabits = 0,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
#define n_boardtypes sizeof(boardtypes)/sizeof(struct dt282x_board)
|
||||
@@ -394,7 +426,8 @@ struct dt282x_private {
|
||||
if (_i){b} \
|
||||
}while (0)
|
||||
|
||||
static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int dt282x_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int dt282x_detach(struct comedi_device *dev);
|
||||
static struct comedi_driver driver_dt282x = {
|
||||
.driver_name = "dt282x",
|
||||
@@ -411,15 +444,17 @@ COMEDI_INITCLEANUP(driver_dt282x);
|
||||
static void free_resources(struct comedi_device *dev);
|
||||
static int prep_ai_dma(struct comedi_device *dev, int chan, int size);
|
||||
static int prep_ao_dma(struct comedi_device *dev, int chan, int size);
|
||||
static int dt282x_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
|
||||
static int dt282x_ao_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
|
||||
static int dt282x_ai_cancel(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s);
|
||||
static int dt282x_ao_cancel(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s);
|
||||
static int dt282x_ns_to_timer(int *nanosec, int round_mode);
|
||||
static void dt282x_disable_dma(struct comedi_device *dev);
|
||||
|
||||
static int dt282x_grab_dma(struct comedi_device *dev, int dma1, int dma2);
|
||||
|
||||
static void dt282x_munge(struct comedi_device *dev, short *buf,
|
||||
unsigned int nbytes)
|
||||
unsigned int nbytes)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned short mask = (1 << boardtype.adbits) - 1;
|
||||
@@ -628,7 +663,7 @@ static irqreturn_t dt282x_interrupt(int irq, void *d)
|
||||
int ret;
|
||||
short data;
|
||||
|
||||
data = (short) inw(dev->iobase + DT2821_ADDAT);
|
||||
data = (short)inw(dev->iobase + DT2821_ADDAT);
|
||||
data &= (1 << boardtype.adbits) - 1;
|
||||
if (devpriv->ad_2scomp) {
|
||||
data ^= 1 << (boardtype.adbits - 1);
|
||||
@@ -654,7 +689,7 @@ static irqreturn_t dt282x_interrupt(int irq, void *d)
|
||||
}
|
||||
|
||||
static void dt282x_load_changain(struct comedi_device *dev, int n,
|
||||
unsigned int *chanlist)
|
||||
unsigned int *chanlist)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int chan, range;
|
||||
@@ -674,8 +709,9 @@ static void dt282x_load_changain(struct comedi_device *dev, int n,
|
||||
* - preload multiplexer
|
||||
* - trigger conversion and wait for it to finish
|
||||
*/
|
||||
static int dt282x_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int dt282x_ai_insn_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -686,18 +722,15 @@ static int dt282x_ai_insn_read(struct comedi_device *dev, struct comedi_subdevic
|
||||
dt282x_load_changain(dev, 1, &insn->chanspec);
|
||||
|
||||
update_supcsr(DT2821_PRLD);
|
||||
wait_for(!mux_busy(), comedi_error(dev, "timeout\n");
|
||||
return -ETIME;
|
||||
);
|
||||
wait_for(!mux_busy(), comedi_error(dev, "timeout\n"); return -ETIME;);
|
||||
|
||||
for (i = 0; i < insn->n; i++) {
|
||||
update_supcsr(DT2821_STRIG);
|
||||
wait_for(ad_done(), comedi_error(dev, "timeout\n");
|
||||
return -ETIME;
|
||||
);
|
||||
return -ETIME;);
|
||||
|
||||
data[i] =
|
||||
inw(dev->iobase +
|
||||
inw(dev->iobase +
|
||||
DT2821_ADDAT) & ((1 << boardtype.adbits) - 1);
|
||||
if (devpriv->ad_2scomp)
|
||||
data[i] ^= (1 << (boardtype.adbits - 1));
|
||||
@@ -706,8 +739,8 @@ static int dt282x_ai_insn_read(struct comedi_device *dev, struct comedi_subdevic
|
||||
return i;
|
||||
}
|
||||
|
||||
static int dt282x_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd)
|
||||
static int dt282x_ai_cmdtest(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_cmd *cmd)
|
||||
{
|
||||
int err = 0;
|
||||
int tmp;
|
||||
@@ -746,7 +779,7 @@ static int dt282x_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice
|
||||
|
||||
/* note that mutual compatiblity is not an issue here */
|
||||
if (cmd->scan_begin_src != TRIG_FOLLOW &&
|
||||
cmd->scan_begin_src != TRIG_EXT)
|
||||
cmd->scan_begin_src != TRIG_EXT)
|
||||
err++;
|
||||
if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
|
||||
err++;
|
||||
@@ -825,7 +858,7 @@ static int dt282x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
|
||||
if (devpriv->usedma == 0) {
|
||||
comedi_error(dev,
|
||||
"driver requires 2 dma channels to execute command");
|
||||
"driver requires 2 dma channels to execute command");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@@ -865,9 +898,7 @@ static int dt282x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
update_adcsr(0);
|
||||
|
||||
update_supcsr(DT2821_PRLD);
|
||||
wait_for(!mux_busy(), comedi_error(dev, "timeout\n");
|
||||
return -ETIME;
|
||||
);
|
||||
wait_for(!mux_busy(), comedi_error(dev, "timeout\n"); return -ETIME;);
|
||||
|
||||
if (cmd->scan_begin_src == TRIG_FOLLOW) {
|
||||
update_supcsr(DT2821_STRIG);
|
||||
@@ -887,7 +918,8 @@ static void dt282x_disable_dma(struct comedi_device *dev)
|
||||
}
|
||||
}
|
||||
|
||||
static int dt282x_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
static int dt282x_ai_cancel(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
dt282x_disable_dma(dev);
|
||||
|
||||
@@ -937,16 +969,18 @@ static int dt282x_ns_to_timer(int *nanosec, int round_mode)
|
||||
* offset binary if necessary, loads the data into the DAC
|
||||
* data register, and performs the conversion.
|
||||
*/
|
||||
static int dt282x_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int dt282x_ao_insn_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
data[0] = devpriv->ao[CR_CHAN(insn->chanspec)];
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dt282x_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int dt282x_ao_insn_write(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
short d;
|
||||
unsigned int chan;
|
||||
@@ -978,8 +1012,8 @@ static int dt282x_ao_insn_write(struct comedi_device *dev, struct comedi_subdevi
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dt282x_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd)
|
||||
static int dt282x_ao_cmdtest(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_cmd *cmd)
|
||||
{
|
||||
int err = 0;
|
||||
int tmp;
|
||||
@@ -1029,7 +1063,7 @@ static int dt282x_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice
|
||||
cmd->start_arg = 0;
|
||||
err++;
|
||||
}
|
||||
if (cmd->scan_begin_arg < 5000 /* XXX unknown */) {
|
||||
if (cmd->scan_begin_arg < 5000 /* XXX unknown */ ) {
|
||||
cmd->scan_begin_arg = 5000;
|
||||
err++;
|
||||
}
|
||||
@@ -1069,8 +1103,8 @@ static int dt282x_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice
|
||||
|
||||
}
|
||||
|
||||
static int dt282x_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
unsigned int x)
|
||||
static int dt282x_ao_inttrig(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, unsigned int x)
|
||||
{
|
||||
int size;
|
||||
|
||||
@@ -1078,7 +1112,7 @@ static int dt282x_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice
|
||||
return -EINVAL;
|
||||
|
||||
size = cfc_read_array_from_buffer(s, devpriv->dma[0].buf,
|
||||
devpriv->dma_maxsize);
|
||||
devpriv->dma_maxsize);
|
||||
if (size == 0) {
|
||||
printk("dt282x: AO underrun\n");
|
||||
return -EPIPE;
|
||||
@@ -1086,7 +1120,7 @@ static int dt282x_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice
|
||||
prep_ao_dma(dev, 0, size);
|
||||
|
||||
size = cfc_read_array_from_buffer(s, devpriv->dma[1].buf,
|
||||
devpriv->dma_maxsize);
|
||||
devpriv->dma_maxsize);
|
||||
if (size == 0) {
|
||||
printk("dt282x: AO underrun\n");
|
||||
return -EPIPE;
|
||||
@@ -1106,7 +1140,7 @@ static int dt282x_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
|
||||
if (devpriv->usedma == 0) {
|
||||
comedi_error(dev,
|
||||
"driver requires 2 dma channels to execute command");
|
||||
"driver requires 2 dma channels to execute command");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@@ -1132,7 +1166,8 @@ static int dt282x_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dt282x_ao_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
static int dt282x_ao_cancel(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
dt282x_disable_dma(dev);
|
||||
|
||||
@@ -1145,8 +1180,9 @@ static int dt282x_ao_cancel(struct comedi_device *dev, struct comedi_subdevice *
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dt282x_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int dt282x_dio_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
if (data[0]) {
|
||||
s->state &= ~data[0];
|
||||
@@ -1159,8 +1195,9 @@ static int dt282x_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevi
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int dt282x_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int dt282x_dio_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int mask;
|
||||
|
||||
@@ -1190,10 +1227,12 @@ static const struct comedi_lrange *const ai_range_table[] = {
|
||||
&range_dt282x_ai_5_bipolar,
|
||||
&range_dt282x_ai_5_unipolar
|
||||
};
|
||||
|
||||
static const struct comedi_lrange *const ai_range_pgl_table[] = {
|
||||
&range_dt282x_ai_hi_bipolar,
|
||||
&range_dt282x_ai_hi_unipolar
|
||||
};
|
||||
|
||||
static const struct comedi_lrange *opt_ai_range_lkup(int ispgl, int x)
|
||||
{
|
||||
if (ispgl) {
|
||||
@@ -1206,6 +1245,7 @@ static const struct comedi_lrange *opt_ai_range_lkup(int ispgl, int x)
|
||||
return ai_range_table[x];
|
||||
}
|
||||
}
|
||||
|
||||
static const struct comedi_lrange *const ao_range_table[] = {
|
||||
&range_bipolar10,
|
||||
&range_unipolar10,
|
||||
@@ -1213,6 +1253,7 @@ static const struct comedi_lrange *const ao_range_table[] = {
|
||||
&range_unipolar5,
|
||||
&range_bipolar2_5
|
||||
};
|
||||
|
||||
static const struct comedi_lrange *opt_ao_range_lkup(int x)
|
||||
{
|
||||
if (x < 0 || x >= 5)
|
||||
@@ -1264,23 +1305,23 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
i = inw(dev->iobase + DT2821_ADCSR);
|
||||
#ifdef DEBUG
|
||||
printk(" fingerprint=%x,%x,%x,%x,%x",
|
||||
inw(dev->iobase + DT2821_ADCSR),
|
||||
inw(dev->iobase + DT2821_CHANCSR),
|
||||
inw(dev->iobase + DT2821_DACSR),
|
||||
inw(dev->iobase + DT2821_SUPCSR),
|
||||
inw(dev->iobase + DT2821_TMRCTR));
|
||||
inw(dev->iobase + DT2821_ADCSR),
|
||||
inw(dev->iobase + DT2821_CHANCSR),
|
||||
inw(dev->iobase + DT2821_DACSR),
|
||||
inw(dev->iobase + DT2821_SUPCSR),
|
||||
inw(dev->iobase + DT2821_TMRCTR));
|
||||
#endif
|
||||
|
||||
if (((inw(dev->iobase + DT2821_ADCSR) & DT2821_ADCSR_MASK)
|
||||
!= DT2821_ADCSR_VAL) ||
|
||||
((inw(dev->iobase + DT2821_CHANCSR) & DT2821_CHANCSR_MASK)
|
||||
!= DT2821_CHANCSR_VAL) ||
|
||||
((inw(dev->iobase + DT2821_DACSR) & DT2821_DACSR_MASK)
|
||||
!= DT2821_DACSR_VAL) ||
|
||||
((inw(dev->iobase + DT2821_SUPCSR) & DT2821_SUPCSR_MASK)
|
||||
!= DT2821_SUPCSR_VAL) ||
|
||||
((inw(dev->iobase + DT2821_TMRCTR) & DT2821_TMRCTR_MASK)
|
||||
!= DT2821_TMRCTR_VAL)) {
|
||||
!= DT2821_ADCSR_VAL) ||
|
||||
((inw(dev->iobase + DT2821_CHANCSR) & DT2821_CHANCSR_MASK)
|
||||
!= DT2821_CHANCSR_VAL) ||
|
||||
((inw(dev->iobase + DT2821_DACSR) & DT2821_DACSR_MASK)
|
||||
!= DT2821_DACSR_VAL) ||
|
||||
((inw(dev->iobase + DT2821_SUPCSR) & DT2821_SUPCSR_MASK)
|
||||
!= DT2821_SUPCSR_VAL) ||
|
||||
((inw(dev->iobase + DT2821_TMRCTR) & DT2821_TMRCTR_MASK)
|
||||
!= DT2821_TMRCTR_VAL)) {
|
||||
printk(" board not found");
|
||||
return -EIO;
|
||||
}
|
||||
@@ -1302,7 +1343,7 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
|
||||
irq = probe_irq_off(irqs);
|
||||
restore_flags(flags);
|
||||
if (0 /* error */) {
|
||||
if (0 /* error */ ) {
|
||||
printk(" error probing irq (bad)");
|
||||
}
|
||||
}
|
||||
@@ -1330,7 +1371,7 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
return ret;
|
||||
|
||||
ret = dt282x_grab_dma(dev, it->options[opt_dma1],
|
||||
it->options[opt_dma2]);
|
||||
it->options[opt_dma2]);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@@ -1344,10 +1385,9 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
/* ai subdevice */
|
||||
s->type = COMEDI_SUBD_AI;
|
||||
s->subdev_flags = SDF_READABLE | SDF_CMD_READ |
|
||||
((it->options[opt_diff]) ? SDF_DIFF : SDF_COMMON);
|
||||
((it->options[opt_diff]) ? SDF_DIFF : SDF_COMMON);
|
||||
s->n_chan =
|
||||
(it->options[opt_diff]) ? boardtype.adchan_di : boardtype.
|
||||
adchan_se;
|
||||
(it->options[opt_diff]) ? boardtype.adchan_di : boardtype.adchan_se;
|
||||
s->insn_read = dt282x_ai_insn_read;
|
||||
s->do_cmdtest = dt282x_ai_cmdtest;
|
||||
s->do_cmd = dt282x_ai_cmd;
|
||||
@@ -1355,7 +1395,7 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
s->maxdata = (1 << boardtype.adbits) - 1;
|
||||
s->len_chanlist = 16;
|
||||
s->range_table =
|
||||
opt_ai_range_lkup(boardtype.ispgl, it->options[opt_ai_range]);
|
||||
opt_ai_range_lkup(boardtype.ispgl, it->options[opt_ai_range]);
|
||||
devpriv->ad_2scomp = it->options[opt_ai_twos];
|
||||
|
||||
s++;
|
||||
@@ -1375,9 +1415,9 @@ static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
s->len_chanlist = 2;
|
||||
s->range_table_list = devpriv->darangelist;
|
||||
devpriv->darangelist[0] =
|
||||
opt_ao_range_lkup(it->options[opt_ao0_range]);
|
||||
opt_ao_range_lkup(it->options[opt_ao0_range]);
|
||||
devpriv->darangelist[1] =
|
||||
opt_ao_range_lkup(it->options[opt_ao1_range]);
|
||||
opt_ao_range_lkup(it->options[opt_ao1_range]);
|
||||
devpriv->da0_2scomp = it->options[opt_ao0_twos];
|
||||
devpriv->da1_2scomp = it->options[opt_ao1_twos];
|
||||
} else {
|
||||
|
||||
@@ -68,18 +68,19 @@ AO commands are not supported.
|
||||
#define PCI_VENDOR_ID_DT 0x1116
|
||||
|
||||
static const struct comedi_lrange range_dt3000_ai = { 4, {
|
||||
RANGE(-10, 10),
|
||||
RANGE(-5, 5),
|
||||
RANGE(-2.5, 2.5),
|
||||
RANGE(-1.25, 1.25)
|
||||
}
|
||||
RANGE(-10, 10),
|
||||
RANGE(-5, 5),
|
||||
RANGE(-2.5, 2.5),
|
||||
RANGE(-1.25, 1.25)
|
||||
}
|
||||
};
|
||||
|
||||
static const struct comedi_lrange range_dt3000_ai_pgl = { 4, {
|
||||
RANGE(-10, 10),
|
||||
RANGE(-1, 1),
|
||||
RANGE(-0.1, 0.1),
|
||||
RANGE(-0.02, 0.02)
|
||||
}
|
||||
RANGE(-10, 10),
|
||||
RANGE(-1, 1),
|
||||
RANGE(-0.1, 0.1),
|
||||
RANGE(-0.02, 0.02)
|
||||
}
|
||||
};
|
||||
|
||||
struct dt3k_boardtype {
|
||||
@@ -94,7 +95,6 @@ struct dt3k_boardtype {
|
||||
int dabits;
|
||||
};
|
||||
|
||||
|
||||
static const struct dt3k_boardtype dt3k_boardtypes[] = {
|
||||
{.name = "dt3001",
|
||||
.device_id = 0x22,
|
||||
@@ -104,7 +104,7 @@ static const struct dt3k_boardtype dt3k_boardtypes[] = {
|
||||
.ai_speed = 3000,
|
||||
.dachan = 2,
|
||||
.dabits = 12,
|
||||
},
|
||||
},
|
||||
{.name = "dt3001-pgl",
|
||||
.device_id = 0x27,
|
||||
.adchan = 16,
|
||||
@@ -113,7 +113,7 @@ static const struct dt3k_boardtype dt3k_boardtypes[] = {
|
||||
.ai_speed = 3000,
|
||||
.dachan = 2,
|
||||
.dabits = 12,
|
||||
},
|
||||
},
|
||||
{.name = "dt3002",
|
||||
.device_id = 0x23,
|
||||
.adchan = 32,
|
||||
@@ -122,7 +122,7 @@ static const struct dt3k_boardtype dt3k_boardtypes[] = {
|
||||
.ai_speed = 3000,
|
||||
.dachan = 0,
|
||||
.dabits = 0,
|
||||
},
|
||||
},
|
||||
{.name = "dt3003",
|
||||
.device_id = 0x24,
|
||||
.adchan = 64,
|
||||
@@ -131,7 +131,7 @@ static const struct dt3k_boardtype dt3k_boardtypes[] = {
|
||||
.ai_speed = 3000,
|
||||
.dachan = 2,
|
||||
.dabits = 12,
|
||||
},
|
||||
},
|
||||
{.name = "dt3003-pgl",
|
||||
.device_id = 0x28,
|
||||
.adchan = 64,
|
||||
@@ -140,7 +140,7 @@ static const struct dt3k_boardtype dt3k_boardtypes[] = {
|
||||
.ai_speed = 3000,
|
||||
.dachan = 2,
|
||||
.dabits = 12,
|
||||
},
|
||||
},
|
||||
{.name = "dt3004",
|
||||
.device_id = 0x25,
|
||||
.adchan = 16,
|
||||
@@ -149,8 +149,8 @@ static const struct dt3k_boardtype dt3k_boardtypes[] = {
|
||||
.ai_speed = 10000,
|
||||
.dachan = 2,
|
||||
.dabits = 12,
|
||||
},
|
||||
{.name = "dt3005", /* a.k.a. 3004-200 */
|
||||
},
|
||||
{.name = "dt3005", /* a.k.a. 3004-200 */
|
||||
.device_id = 0x26,
|
||||
.adchan = 16,
|
||||
.adbits = 16,
|
||||
@@ -158,21 +158,22 @@ static const struct dt3k_boardtype dt3k_boardtypes[] = {
|
||||
.ai_speed = 5000,
|
||||
.dachan = 2,
|
||||
.dabits = 12,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
#define n_dt3k_boards sizeof(dt3k_boardtypes)/sizeof(struct dt3k_boardtype)
|
||||
#define this_board ((const struct dt3k_boardtype *)dev->board_ptr)
|
||||
|
||||
static DEFINE_PCI_DEVICE_TABLE(dt3k_pci_table) = {
|
||||
{PCI_VENDOR_ID_DT, 0x0022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_DT, 0x0027, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_DT, 0x0023, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_DT, 0x0024, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_DT, 0x0028, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_DT, 0x0025, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_DT, 0x0026, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{0}
|
||||
{
|
||||
PCI_VENDOR_ID_DT, 0x0022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_DT, 0x0027, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_DT, 0x0023, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_DT, 0x0024, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_DT, 0x0028, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_DT, 0x0025, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_DT, 0x0026, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
0}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, dt3k_pci_table);
|
||||
@@ -276,7 +277,8 @@ struct dt3k_private {
|
||||
|
||||
#define devpriv ((struct dt3k_private *)dev->private)
|
||||
|
||||
static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int dt3000_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int dt3000_detach(struct comedi_device *dev);
|
||||
static struct comedi_driver driver_dt3000 = {
|
||||
.driver_name = "dt3000",
|
||||
@@ -287,10 +289,12 @@ static struct comedi_driver driver_dt3000 = {
|
||||
|
||||
COMEDI_PCI_INITCLEANUP(driver_dt3000, dt3k_pci_table);
|
||||
|
||||
static void dt3k_ai_empty_fifo(struct comedi_device *dev, struct comedi_subdevice *s);
|
||||
static void dt3k_ai_empty_fifo(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s);
|
||||
static int dt3k_ns_to_timer(unsigned int timer_base, unsigned int *arg,
|
||||
unsigned int round_mode);
|
||||
static int dt3k_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
|
||||
unsigned int round_mode);
|
||||
static int dt3k_ai_cancel(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s);
|
||||
#ifdef DEBUG
|
||||
static void debug_intr_flags(unsigned int flags);
|
||||
#endif
|
||||
@@ -319,8 +323,9 @@ static int dt3k_send_cmd(struct comedi_device *dev, unsigned int cmd)
|
||||
return -ETIME;
|
||||
}
|
||||
|
||||
static unsigned int dt3k_readsingle(struct comedi_device *dev, unsigned int subsys,
|
||||
unsigned int chan, unsigned int gain)
|
||||
static unsigned int dt3k_readsingle(struct comedi_device *dev,
|
||||
unsigned int subsys, unsigned int chan,
|
||||
unsigned int gain)
|
||||
{
|
||||
writew(subsys, devpriv->io_addr + DPR_SubSys);
|
||||
|
||||
@@ -333,7 +338,7 @@ static unsigned int dt3k_readsingle(struct comedi_device *dev, unsigned int subs
|
||||
}
|
||||
|
||||
static void dt3k_writesingle(struct comedi_device *dev, unsigned int subsys,
|
||||
unsigned int chan, unsigned int data)
|
||||
unsigned int chan, unsigned int data)
|
||||
{
|
||||
writew(subsys, devpriv->io_addr + DPR_SubSys);
|
||||
|
||||
@@ -388,6 +393,7 @@ static char *intr_flags[] = {
|
||||
"AdFull", "AdSwError", "AdHwError", "DaEmpty",
|
||||
"DaSwError", "DaHwError", "CtDone", "CmDone",
|
||||
};
|
||||
|
||||
static void debug_intr_flags(unsigned int flags)
|
||||
{
|
||||
int i;
|
||||
@@ -401,7 +407,8 @@ static void debug_intr_flags(unsigned int flags)
|
||||
}
|
||||
#endif
|
||||
|
||||
static void dt3k_ai_empty_fifo(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
static void dt3k_ai_empty_fifo(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
int front;
|
||||
int rear;
|
||||
@@ -430,8 +437,8 @@ static void dt3k_ai_empty_fifo(struct comedi_device *dev, struct comedi_subdevic
|
||||
writew(rear, devpriv->io_addr + DPR_AD_Buf_Rear);
|
||||
}
|
||||
|
||||
static int dt3k_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd)
|
||||
static int dt3k_ai_cmdtest(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_cmd *cmd)
|
||||
{
|
||||
int err = 0;
|
||||
int tmp;
|
||||
@@ -528,7 +535,7 @@ static int dt3k_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s
|
||||
if (cmd->scan_begin_src == TRIG_TIMER) {
|
||||
tmp = cmd->scan_begin_arg;
|
||||
dt3k_ns_to_timer(100, &cmd->scan_begin_arg,
|
||||
cmd->flags & TRIG_ROUND_MASK);
|
||||
cmd->flags & TRIG_ROUND_MASK);
|
||||
if (tmp != cmd->scan_begin_arg)
|
||||
err++;
|
||||
} else {
|
||||
@@ -537,14 +544,14 @@ static int dt3k_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s
|
||||
if (cmd->convert_src == TRIG_TIMER) {
|
||||
tmp = cmd->convert_arg;
|
||||
dt3k_ns_to_timer(50, &cmd->convert_arg,
|
||||
cmd->flags & TRIG_ROUND_MASK);
|
||||
cmd->flags & TRIG_ROUND_MASK);
|
||||
if (tmp != cmd->convert_arg)
|
||||
err++;
|
||||
if (cmd->scan_begin_src == TRIG_TIMER &&
|
||||
cmd->scan_begin_arg <
|
||||
cmd->convert_arg * cmd->scan_end_arg) {
|
||||
cmd->scan_begin_arg <
|
||||
cmd->convert_arg * cmd->scan_end_arg) {
|
||||
cmd->scan_begin_arg =
|
||||
cmd->convert_arg * cmd->scan_end_arg;
|
||||
cmd->convert_arg * cmd->scan_end_arg;
|
||||
err++;
|
||||
}
|
||||
} else {
|
||||
@@ -558,7 +565,7 @@ static int dt3k_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s
|
||||
}
|
||||
|
||||
static int dt3k_ns_to_timer(unsigned int timer_base, unsigned int *nanosec,
|
||||
unsigned int round_mode)
|
||||
unsigned int round_mode)
|
||||
{
|
||||
int divider, base, prescale;
|
||||
|
||||
@@ -608,7 +615,7 @@ static int dt3k_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
range = CR_RANGE(cmd->chanlist[i]);
|
||||
|
||||
writew((range << 6) | chan,
|
||||
devpriv->io_addr + DPR_ADC_buffer + i);
|
||||
devpriv->io_addr + DPR_ADC_buffer + i);
|
||||
}
|
||||
aref = CR_AREF(cmd->chanlist[0]);
|
||||
|
||||
@@ -617,7 +624,7 @@ static int dt3k_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
|
||||
if (cmd->convert_src == TRIG_TIMER) {
|
||||
divider = dt3k_ns_to_timer(50, &cmd->convert_arg,
|
||||
cmd->flags & TRIG_ROUND_MASK);
|
||||
cmd->flags & TRIG_ROUND_MASK);
|
||||
writew((divider >> 16), devpriv->io_addr + DPR_Params(1));
|
||||
printk("param[1]=0x%04x\n", divider >> 16);
|
||||
writew((divider & 0xffff), devpriv->io_addr + DPR_Params(2));
|
||||
@@ -628,7 +635,7 @@ static int dt3k_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
|
||||
if (cmd->scan_begin_src == TRIG_TIMER) {
|
||||
tscandiv = dt3k_ns_to_timer(100, &cmd->scan_begin_arg,
|
||||
cmd->flags & TRIG_ROUND_MASK);
|
||||
cmd->flags & TRIG_ROUND_MASK);
|
||||
writew((tscandiv >> 16), devpriv->io_addr + DPR_Params(3));
|
||||
printk("param[3]=0x%04x\n", tscandiv >> 16);
|
||||
writew((tscandiv & 0xffff), devpriv->io_addr + DPR_Params(4));
|
||||
@@ -650,7 +657,7 @@ static int dt3k_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
ret = dt3k_send_cmd(dev, CMD_CONFIG);
|
||||
|
||||
writew(DT3000_ADFULL | DT3000_ADSWERR | DT3000_ADHWERR,
|
||||
devpriv->io_addr + DPR_Int_Mask);
|
||||
devpriv->io_addr + DPR_Int_Mask);
|
||||
|
||||
debug_n_ints = 0;
|
||||
|
||||
@@ -673,7 +680,7 @@ static int dt3k_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
}
|
||||
|
||||
static int dt3k_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int i;
|
||||
unsigned int chan, gain, aref;
|
||||
@@ -691,7 +698,7 @@ static int dt3k_ai_insn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
}
|
||||
|
||||
static int dt3k_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int i;
|
||||
unsigned int chan;
|
||||
@@ -705,8 +712,9 @@ static int dt3k_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
return i;
|
||||
}
|
||||
|
||||
static int dt3k_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int dt3k_ao_insn_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int i;
|
||||
unsigned int chan;
|
||||
@@ -734,8 +742,9 @@ static void dt3k_dio_config(struct comedi_device *dev, int bits)
|
||||
dt3k_send_cmd(dev, CMD_CONFIG);
|
||||
}
|
||||
|
||||
static int dt3k_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int dt3k_dio_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int mask;
|
||||
|
||||
@@ -750,9 +759,9 @@ static int dt3k_dio_insn_config(struct comedi_device *dev, struct comedi_subdevi
|
||||
break;
|
||||
case INSN_CONFIG_DIO_QUERY:
|
||||
data[1] =
|
||||
(s->io_bits & (1 << CR_CHAN(insn->
|
||||
chanspec))) ? COMEDI_OUTPUT :
|
||||
COMEDI_INPUT;
|
||||
(s->
|
||||
io_bits & (1 << CR_CHAN(insn->chanspec))) ? COMEDI_OUTPUT :
|
||||
COMEDI_INPUT;
|
||||
return insn->n;
|
||||
break;
|
||||
default:
|
||||
@@ -765,8 +774,9 @@ static int dt3k_dio_insn_config(struct comedi_device *dev, struct comedi_subdevi
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
static int dt3k_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int dt3k_dio_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
if (insn->n != 2)
|
||||
return -EINVAL;
|
||||
@@ -781,8 +791,9 @@ static int dt3k_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int dt3k_mem_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int dt3k_mem_insn_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
unsigned int addr = CR_CHAN(insn->chanspec);
|
||||
int i;
|
||||
@@ -925,8 +936,8 @@ static int dt_pci_probe(struct comedi_device *dev, int bus, int slot)
|
||||
pcidev = NULL;
|
||||
while ((pcidev = dt_pci_find_device(pcidev, &board)) != NULL) {
|
||||
if ((bus == 0 && slot == 0) ||
|
||||
(pcidev->bus->number == bus &&
|
||||
PCI_SLOT(pcidev->devfn) == slot)) {
|
||||
(pcidev->bus->number == bus &&
|
||||
PCI_SLOT(pcidev->devfn) == slot)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -961,7 +972,7 @@ static int setup_pci(struct comedi_device *dev)
|
||||
return -ENOMEM;
|
||||
#if DEBUG
|
||||
printk("0x%08llx mapped to %p, ",
|
||||
(unsigned long long)devpriv->phys_addr, devpriv->io_addr);
|
||||
(unsigned long long)devpriv->phys_addr, devpriv->io_addr);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
@@ -972,15 +983,17 @@ static struct pci_dev *dt_pci_find_device(struct pci_dev *from, int *board)
|
||||
int i;
|
||||
|
||||
for (from = pci_get_device(PCI_VENDOR_ID_DT, PCI_ANY_ID, from);
|
||||
from != NULL;
|
||||
from = pci_get_device(PCI_VENDOR_ID_DT, PCI_ANY_ID, from)) {
|
||||
from != NULL;
|
||||
from = pci_get_device(PCI_VENDOR_ID_DT, PCI_ANY_ID, from)) {
|
||||
for (i = 0; i < n_dt3k_boards; i++) {
|
||||
if (from->device == dt3k_boardtypes[i].device_id) {
|
||||
*board = i;
|
||||
return from;
|
||||
}
|
||||
}
|
||||
printk("unknown Data Translation PCI device found with device_id=0x%04x\n", from->device);
|
||||
printk
|
||||
("unknown Data Translation PCI device found with device_id=0x%04x\n",
|
||||
from->device);
|
||||
}
|
||||
*board = -1;
|
||||
return from;
|
||||
|
||||
@@ -89,9 +89,9 @@ for my needs.
|
||||
#define F020_MASK_DACxCN_DACxEN 0x80
|
||||
|
||||
enum {
|
||||
/* A/D D/A DI DO CT */
|
||||
/* A/D D/A DI DO CT */
|
||||
DT9812_DEVID_DT9812_10, /* 8 2 8 8 1 +/- 10V */
|
||||
DT9812_DEVID_DT9812_2PT5,/* 8 2 8 8 1 0-2.44V */
|
||||
DT9812_DEVID_DT9812_2PT5, /* 8 2 8 8 1 0-2.44V */
|
||||
#if 0
|
||||
DT9812_DEVID_DT9813, /* 16 2 4 4 1 +/- 10V */
|
||||
DT9812_DEVID_DT9814 /* 24 2 0 0 1 +/- 10V */
|
||||
@@ -266,7 +266,7 @@ static DECLARE_MUTEX(dt9812_mutex);
|
||||
|
||||
static struct usb_device_id dt9812_table[] = {
|
||||
{USB_DEVICE(0x0867, 0x9812)},
|
||||
{ } /* Terminating entry */
|
||||
{} /* Terminating entry */
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(usb, dt9812_table);
|
||||
@@ -301,23 +301,23 @@ struct slot_dt9812 {
|
||||
};
|
||||
|
||||
static const struct comedi_lrange dt9812_10_ain_range = { 1, {
|
||||
BIP_RANGE(10),
|
||||
}
|
||||
BIP_RANGE(10),
|
||||
}
|
||||
};
|
||||
|
||||
static const struct comedi_lrange dt9812_2pt5_ain_range = { 1, {
|
||||
UNI_RANGE(2.5),
|
||||
}
|
||||
UNI_RANGE(2.5),
|
||||
}
|
||||
};
|
||||
|
||||
static const struct comedi_lrange dt9812_10_aout_range = { 1, {
|
||||
BIP_RANGE(10),
|
||||
}
|
||||
BIP_RANGE(10),
|
||||
}
|
||||
};
|
||||
|
||||
static const struct comedi_lrange dt9812_2pt5_aout_range = { 1, {
|
||||
UNI_RANGE(2.5),
|
||||
}
|
||||
UNI_RANGE(2.5),
|
||||
}
|
||||
};
|
||||
|
||||
static struct slot_dt9812 dt9812[DT9812_NUM_SLOTS];
|
||||
@@ -346,7 +346,7 @@ static int dt9812_read_info(struct usb_dt9812 *dev, int offset, void *buf,
|
||||
|
||||
cmd.cmd = cpu_to_le32(DT9812_R_FLASH_DATA);
|
||||
cmd.u.flash_data_info.address =
|
||||
cpu_to_le16(DT9812_DIAGS_BOARD_INFO_ADDR + offset);
|
||||
cpu_to_le16(DT9812_DIAGS_BOARD_INFO_ADDR + offset);
|
||||
cmd.u.flash_data_info.numbytes = cpu_to_le16(buf_size);
|
||||
|
||||
/* DT9812 only responds to 32 byte writes!! */
|
||||
@@ -365,7 +365,7 @@ static int dt9812_read_info(struct usb_dt9812 *dev, int offset, void *buf,
|
||||
}
|
||||
|
||||
static int dt9812_read_multiple_registers(struct usb_dt9812 *dev, int reg_count,
|
||||
u8 *address, u8 *value)
|
||||
u8 * address, u8 * value)
|
||||
{
|
||||
struct dt9812_usb_cmd cmd;
|
||||
int i, count, retval;
|
||||
@@ -391,8 +391,8 @@ static int dt9812_read_multiple_registers(struct usb_dt9812 *dev, int reg_count,
|
||||
}
|
||||
|
||||
static int dt9812_write_multiple_registers(struct usb_dt9812 *dev,
|
||||
int reg_count, u8 *address,
|
||||
u8 *value)
|
||||
int reg_count, u8 * address,
|
||||
u8 * value)
|
||||
{
|
||||
struct dt9812_usb_cmd cmd;
|
||||
int i, count, retval;
|
||||
@@ -430,7 +430,7 @@ static int dt9812_rmw_multiple_registers(struct usb_dt9812 *dev, int reg_count,
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int dt9812_digital_in(struct slot_dt9812 *slot, u8 *bits)
|
||||
static int dt9812_digital_in(struct slot_dt9812 *slot, u8 * bits)
|
||||
{
|
||||
int result = -ENODEV;
|
||||
|
||||
@@ -449,7 +449,7 @@ static int dt9812_digital_in(struct slot_dt9812 *slot, u8 *bits)
|
||||
*/
|
||||
*bits = (value[0] & 0x7f) | ((value[1] & 0x08) << 4);
|
||||
/* printk("%2.2x, %2.2x -> %2.2x\n",
|
||||
value[0], value[1], *bits); */
|
||||
value[0], value[1], *bits); */
|
||||
}
|
||||
}
|
||||
up(&slot->mutex);
|
||||
@@ -476,7 +476,7 @@ static int dt9812_digital_out(struct slot_dt9812 *slot, u8 bits)
|
||||
return result;
|
||||
}
|
||||
|
||||
static int dt9812_digital_out_shadow(struct slot_dt9812 *slot, u8 *bits)
|
||||
static int dt9812_digital_out_shadow(struct slot_dt9812 *slot, u8 * bits)
|
||||
{
|
||||
int result = -ENODEV;
|
||||
|
||||
@@ -516,8 +516,7 @@ static void dt9812_configure_gain(struct usb_dt9812 *dev,
|
||||
|
||||
rmw->address = F020_SFR_ADC0CF;
|
||||
rmw->and_mask = F020_MASK_ADC0CF_AMP0GN2 |
|
||||
F020_MASK_ADC0CF_AMP0GN1 |
|
||||
F020_MASK_ADC0CF_AMP0GN0;
|
||||
F020_MASK_ADC0CF_AMP0GN1 | F020_MASK_ADC0CF_AMP0GN0;
|
||||
switch (gain) {
|
||||
/*
|
||||
* 000 -> Gain = 1
|
||||
@@ -529,7 +528,7 @@ static void dt9812_configure_gain(struct usb_dt9812 *dev,
|
||||
*/
|
||||
case DT9812_GAIN_0PT5:
|
||||
rmw->or_value = F020_MASK_ADC0CF_AMP0GN2 ||
|
||||
F020_MASK_ADC0CF_AMP0GN1;
|
||||
F020_MASK_ADC0CF_AMP0GN1;
|
||||
break;
|
||||
case DT9812_GAIN_1:
|
||||
rmw->or_value = 0x00;
|
||||
@@ -542,7 +541,7 @@ static void dt9812_configure_gain(struct usb_dt9812 *dev,
|
||||
break;
|
||||
case DT9812_GAIN_8:
|
||||
rmw->or_value = F020_MASK_ADC0CF_AMP0GN1 ||
|
||||
F020_MASK_ADC0CF_AMP0GN0;
|
||||
F020_MASK_ADC0CF_AMP0GN0;
|
||||
break;
|
||||
case DT9812_GAIN_16:
|
||||
rmw->or_value = F020_MASK_ADC0CF_AMP0GN2;
|
||||
@@ -553,7 +552,7 @@ static void dt9812_configure_gain(struct usb_dt9812 *dev,
|
||||
}
|
||||
}
|
||||
|
||||
static int dt9812_analog_in(struct slot_dt9812 *slot, int channel, u16 *value,
|
||||
static int dt9812_analog_in(struct slot_dt9812 *slot, int channel, u16 * value,
|
||||
enum dt9812_gain gain)
|
||||
{
|
||||
struct dt9812_rmw_byte rmw[3];
|
||||
@@ -620,7 +619,7 @@ static int dt9812_analog_in(struct slot_dt9812 *slot, int channel, u16 *value,
|
||||
}
|
||||
|
||||
static int dt9812_analog_out_shadow(struct slot_dt9812 *slot, int channel,
|
||||
u16 *value)
|
||||
u16 * value)
|
||||
{
|
||||
int result = -ENODEV;
|
||||
|
||||
@@ -729,32 +728,32 @@ static int dt9812_probe(struct usb_interface *interface,
|
||||
direction = USB_DIR_IN;
|
||||
dev->message_pipe.addr = endpoint->bEndpointAddress;
|
||||
dev->message_pipe.size =
|
||||
le16_to_cpu(endpoint->wMaxPacketSize);
|
||||
le16_to_cpu(endpoint->wMaxPacketSize);
|
||||
|
||||
break;
|
||||
case 1:
|
||||
direction = USB_DIR_OUT;
|
||||
dev->command_write.addr = endpoint->bEndpointAddress;
|
||||
dev->command_write.size =
|
||||
le16_to_cpu(endpoint->wMaxPacketSize);
|
||||
le16_to_cpu(endpoint->wMaxPacketSize);
|
||||
break;
|
||||
case 2:
|
||||
direction = USB_DIR_IN;
|
||||
dev->command_read.addr = endpoint->bEndpointAddress;
|
||||
dev->command_read.size =
|
||||
le16_to_cpu(endpoint->wMaxPacketSize);
|
||||
le16_to_cpu(endpoint->wMaxPacketSize);
|
||||
break;
|
||||
case 3:
|
||||
direction = USB_DIR_OUT;
|
||||
dev->write_stream.addr = endpoint->bEndpointAddress;
|
||||
dev->write_stream.size =
|
||||
le16_to_cpu(endpoint->wMaxPacketSize);
|
||||
le16_to_cpu(endpoint->wMaxPacketSize);
|
||||
break;
|
||||
case 4:
|
||||
direction = USB_DIR_IN;
|
||||
dev->read_stream.addr = endpoint->bEndpointAddress;
|
||||
dev->read_stream.size =
|
||||
le16_to_cpu(endpoint->wMaxPacketSize);
|
||||
le16_to_cpu(endpoint->wMaxPacketSize);
|
||||
break;
|
||||
}
|
||||
if ((endpoint->bEndpointAddress & USB_DIR_IN) != direction) {
|
||||
@@ -786,8 +785,7 @@ static int dt9812_probe(struct usb_interface *interface,
|
||||
retval = -ENODEV;
|
||||
goto error;
|
||||
}
|
||||
if (dt9812_read_info(dev, 3, &dev->product,
|
||||
sizeof(dev->product)) != 0) {
|
||||
if (dt9812_read_info(dev, 3, &dev->product, sizeof(dev->product)) != 0) {
|
||||
err("Failed to read product.");
|
||||
retval = -ENODEV;
|
||||
goto error;
|
||||
@@ -940,8 +938,9 @@ static void dt9812_comedi_open(struct comedi_device *dev)
|
||||
up(&devpriv->slot->mutex);
|
||||
}
|
||||
|
||||
static int dt9812_di_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int dt9812_di_rinsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
int n;
|
||||
u8 bits = 0;
|
||||
@@ -952,8 +951,9 @@ static int dt9812_di_rinsn(struct comedi_device *dev, struct comedi_subdevice *s
|
||||
return n;
|
||||
}
|
||||
|
||||
static int dt9812_do_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int dt9812_do_winsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
int n;
|
||||
u8 bits = 0;
|
||||
@@ -970,8 +970,9 @@ static int dt9812_do_winsn(struct comedi_device *dev, struct comedi_subdevice *s
|
||||
return n;
|
||||
}
|
||||
|
||||
static int dt9812_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int dt9812_ai_rinsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
int n;
|
||||
|
||||
@@ -985,8 +986,9 @@ static int dt9812_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s
|
||||
return n;
|
||||
}
|
||||
|
||||
static int dt9812_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int dt9812_ao_rinsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
int n;
|
||||
u16 value;
|
||||
@@ -999,8 +1001,9 @@ static int dt9812_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s
|
||||
return n;
|
||||
}
|
||||
|
||||
static int dt9812_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int dt9812_ao_winsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
int n;
|
||||
|
||||
|
||||
@@ -32,14 +32,14 @@ struct fl512_private {
|
||||
#define devpriv ((struct fl512_private *) dev->private)
|
||||
|
||||
static const struct comedi_lrange range_fl512 = { 4, {
|
||||
BIP_RANGE(0.5),
|
||||
BIP_RANGE(1),
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(10),
|
||||
UNI_RANGE(1),
|
||||
UNI_RANGE(5),
|
||||
UNI_RANGE(10),
|
||||
}
|
||||
BIP_RANGE(0.5),
|
||||
BIP_RANGE(1),
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(10),
|
||||
UNI_RANGE(1),
|
||||
UNI_RANGE(5),
|
||||
UNI_RANGE(10),
|
||||
}
|
||||
};
|
||||
|
||||
static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
@@ -55,17 +55,20 @@ static struct comedi_driver driver_fl512 = {
|
||||
COMEDI_INITCLEANUP(driver_fl512);
|
||||
|
||||
static int fl512_ai_insn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
|
||||
static int fl512_ao_insn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
static int fl512_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int fl512_ao_insn_readback(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
/*
|
||||
* fl512_ai_insn : this is the analog input function
|
||||
*/
|
||||
static int fl512_ai_insn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
int n;
|
||||
unsigned int lo_byte, hi_byte;
|
||||
@@ -90,7 +93,8 @@ static int fl512_ai_insn(struct comedi_device *dev,
|
||||
* fl512_ao_insn : used to write to a DA port n times
|
||||
*/
|
||||
static int fl512_ao_insn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
int n;
|
||||
int chan = CR_CHAN(insn->chanspec); /* get chan to write */
|
||||
@@ -111,7 +115,8 @@ static int fl512_ao_insn(struct comedi_device *dev,
|
||||
* DA port
|
||||
*/
|
||||
static int fl512_ao_insn_readback(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int n;
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
@@ -130,7 +135,7 @@ static int fl512_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
{
|
||||
unsigned long iobase;
|
||||
struct comedi_subdevice *s; /* pointer to the subdevice:
|
||||
Analog in, Analog out, ( not made ->and Digital IO) */
|
||||
Analog in, Analog out, ( not made ->and Digital IO) */
|
||||
|
||||
iobase = it->options[0];
|
||||
printk("comedi:%d fl512: 0x%04lx", dev->minor, iobase);
|
||||
|
||||
@@ -58,7 +58,7 @@ static int hpdi_detach(struct comedi_device *dev);
|
||||
void abort_dma(struct comedi_device *dev, unsigned int channel);
|
||||
static int hpdi_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
|
||||
static int hpdi_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd);
|
||||
struct comedi_cmd *cmd);
|
||||
static int hpdi_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
|
||||
static irqreturn_t handle_interrupt(int irq, void *d);
|
||||
static int dio_config_block_size(struct comedi_device *dev, unsigned int *data);
|
||||
@@ -149,7 +149,7 @@ enum board_control_bits {
|
||||
TEST_MODE_ENABLE_BIT = 0x80000000,
|
||||
};
|
||||
uint32_t command_discrete_output_bits(unsigned int channel, int output,
|
||||
int output_value)
|
||||
int output_value)
|
||||
{
|
||||
uint32_t bits = 0;
|
||||
|
||||
@@ -193,11 +193,13 @@ uint32_t almost_empty_bits(unsigned int num_words)
|
||||
{
|
||||
return num_words & 0xffff;
|
||||
}
|
||||
|
||||
unsigned int almost_full_num_words(uint32_t bits)
|
||||
{
|
||||
/* XXX need to add or subtract one? */
|
||||
return (bits >> 16) & 0xffff;
|
||||
}
|
||||
|
||||
unsigned int almost_empty_num_words(uint32_t bits)
|
||||
{
|
||||
return bits & 0xffff;
|
||||
@@ -268,33 +270,33 @@ struct hpdi_board {
|
||||
int subdevice_id; /* pci subdevice id */
|
||||
};
|
||||
|
||||
|
||||
static const struct hpdi_board hpdi_boards[] = {
|
||||
{
|
||||
.name = "pci-hpdi32",
|
||||
.device_id = PCI_DEVICE_ID_PLX_9080,
|
||||
.subdevice_id = 0x2400,
|
||||
},
|
||||
.name = "pci-hpdi32",
|
||||
.device_id = PCI_DEVICE_ID_PLX_9080,
|
||||
.subdevice_id = 0x2400,
|
||||
},
|
||||
#if 0
|
||||
{
|
||||
.name = "pxi-hpdi32",
|
||||
.device_id = 0x9656,
|
||||
.subdevice_id = 0x2705,
|
||||
},
|
||||
.name = "pxi-hpdi32",
|
||||
.device_id = 0x9656,
|
||||
.subdevice_id = 0x2705,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
static DEFINE_PCI_DEVICE_TABLE(hpdi_pci_table) = {
|
||||
{PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9080, PCI_VENDOR_ID_PLX, 0x2400,
|
||||
0, 0, 0},
|
||||
{0}
|
||||
{
|
||||
PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9080, PCI_VENDOR_ID_PLX,
|
||||
0x2400, 0, 0, 0}, {
|
||||
0}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, hpdi_pci_table);
|
||||
|
||||
static inline struct hpdi_board *board(const struct comedi_device * dev)
|
||||
static inline struct hpdi_board *board(const struct comedi_device *dev)
|
||||
{
|
||||
return (struct hpdi_board *) dev->board_ptr;
|
||||
return (struct hpdi_board *)dev->board_ptr;
|
||||
}
|
||||
|
||||
struct hpdi_private {
|
||||
@@ -321,8 +323,7 @@ struct hpdi_private {
|
||||
unsigned dio_config_output:1;
|
||||
};
|
||||
|
||||
|
||||
static inline struct hpdi_private *priv(struct comedi_device * dev)
|
||||
static inline struct hpdi_private *priv(struct comedi_device *dev)
|
||||
{
|
||||
return dev->private;
|
||||
}
|
||||
@@ -336,8 +337,9 @@ static struct comedi_driver driver_hpdi = {
|
||||
|
||||
COMEDI_PCI_INITCLEANUP(driver_hpdi, hpdi_pci_table);
|
||||
|
||||
static int dio_config_insn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int dio_config_insn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
switch (data[0]) {
|
||||
case INSN_CONFIG_DIO_OUTPUT:
|
||||
@@ -350,8 +352,7 @@ static int dio_config_insn(struct comedi_device *dev, struct comedi_subdevice *s
|
||||
break;
|
||||
case INSN_CONFIG_DIO_QUERY:
|
||||
data[1] =
|
||||
priv(dev)->
|
||||
dio_config_output ? COMEDI_OUTPUT : COMEDI_INPUT;
|
||||
priv(dev)->dio_config_output ? COMEDI_OUTPUT : COMEDI_INPUT;
|
||||
return insn->n;
|
||||
break;
|
||||
case INSN_CONFIG_BLOCK_SIZE:
|
||||
@@ -377,29 +378,29 @@ static void init_plx9080(struct comedi_device *dev)
|
||||
|
||||
/* plx9080 dump */
|
||||
DEBUG_PRINT(" plx interrupt status 0x%x\n",
|
||||
readl(plx_iobase + PLX_INTRCS_REG));
|
||||
readl(plx_iobase + PLX_INTRCS_REG));
|
||||
DEBUG_PRINT(" plx id bits 0x%x\n", readl(plx_iobase + PLX_ID_REG));
|
||||
DEBUG_PRINT(" plx control reg 0x%x\n",
|
||||
readl(priv(dev)->plx9080_iobase + PLX_CONTROL_REG));
|
||||
readl(priv(dev)->plx9080_iobase + PLX_CONTROL_REG));
|
||||
|
||||
DEBUG_PRINT(" plx revision 0x%x\n",
|
||||
readl(plx_iobase + PLX_REVISION_REG));
|
||||
readl(plx_iobase + PLX_REVISION_REG));
|
||||
DEBUG_PRINT(" plx dma channel 0 mode 0x%x\n",
|
||||
readl(plx_iobase + PLX_DMA0_MODE_REG));
|
||||
readl(plx_iobase + PLX_DMA0_MODE_REG));
|
||||
DEBUG_PRINT(" plx dma channel 1 mode 0x%x\n",
|
||||
readl(plx_iobase + PLX_DMA1_MODE_REG));
|
||||
readl(plx_iobase + PLX_DMA1_MODE_REG));
|
||||
DEBUG_PRINT(" plx dma channel 0 pci address 0x%x\n",
|
||||
readl(plx_iobase + PLX_DMA0_PCI_ADDRESS_REG));
|
||||
readl(plx_iobase + PLX_DMA0_PCI_ADDRESS_REG));
|
||||
DEBUG_PRINT(" plx dma channel 0 local address 0x%x\n",
|
||||
readl(plx_iobase + PLX_DMA0_LOCAL_ADDRESS_REG));
|
||||
readl(plx_iobase + PLX_DMA0_LOCAL_ADDRESS_REG));
|
||||
DEBUG_PRINT(" plx dma channel 0 transfer size 0x%x\n",
|
||||
readl(plx_iobase + PLX_DMA0_TRANSFER_SIZE_REG));
|
||||
readl(plx_iobase + PLX_DMA0_TRANSFER_SIZE_REG));
|
||||
DEBUG_PRINT(" plx dma channel 0 descriptor 0x%x\n",
|
||||
readl(plx_iobase + PLX_DMA0_DESCRIPTOR_REG));
|
||||
readl(plx_iobase + PLX_DMA0_DESCRIPTOR_REG));
|
||||
DEBUG_PRINT(" plx dma channel 0 command status 0x%x\n",
|
||||
readb(plx_iobase + PLX_DMA0_CS_REG));
|
||||
readb(plx_iobase + PLX_DMA0_CS_REG));
|
||||
DEBUG_PRINT(" plx dma channel 0 threshold 0x%x\n",
|
||||
readl(plx_iobase + PLX_DMA0_THRESHOLD_REG));
|
||||
readl(plx_iobase + PLX_DMA0_THRESHOLD_REG));
|
||||
DEBUG_PRINT(" plx bigend 0x%x\n", readl(plx_iobase + PLX_BIGEND_REG));
|
||||
#ifdef __BIG_ENDIAN
|
||||
bits = BIGEND_DMA0 | BIGEND_DMA1;
|
||||
@@ -448,7 +449,7 @@ static int setup_subdevices(struct comedi_device *dev)
|
||||
/* dev->write_subdev = s; */
|
||||
s->type = COMEDI_SUBD_DIO;
|
||||
s->subdev_flags =
|
||||
SDF_READABLE | SDF_WRITEABLE | SDF_LSAMPL | SDF_CMD_READ;
|
||||
SDF_READABLE | SDF_WRITEABLE | SDF_LSAMPL | SDF_CMD_READ;
|
||||
s->n_chan = 32;
|
||||
s->len_chanlist = 32;
|
||||
s->maxdata = 1;
|
||||
@@ -469,21 +470,21 @@ static int init_hpdi(struct comedi_device *dev)
|
||||
udelay(10);
|
||||
|
||||
writel(almost_empty_bits(32) | almost_full_bits(32),
|
||||
priv(dev)->hpdi_iobase + RX_PROG_ALMOST_REG);
|
||||
priv(dev)->hpdi_iobase + RX_PROG_ALMOST_REG);
|
||||
writel(almost_empty_bits(32) | almost_full_bits(32),
|
||||
priv(dev)->hpdi_iobase + TX_PROG_ALMOST_REG);
|
||||
priv(dev)->hpdi_iobase + TX_PROG_ALMOST_REG);
|
||||
|
||||
priv(dev)->tx_fifo_size = fifo_size(readl(priv(dev)->hpdi_iobase +
|
||||
TX_FIFO_SIZE_REG));
|
||||
TX_FIFO_SIZE_REG));
|
||||
priv(dev)->rx_fifo_size = fifo_size(readl(priv(dev)->hpdi_iobase +
|
||||
RX_FIFO_SIZE_REG));
|
||||
RX_FIFO_SIZE_REG));
|
||||
|
||||
writel(0, priv(dev)->hpdi_iobase + INTERRUPT_CONTROL_REG);
|
||||
|
||||
/* enable interrupts */
|
||||
plx_intcsr_bits =
|
||||
ICS_AERR | ICS_PERR | ICS_PIE | ICS_PLIE | ICS_PAIE | ICS_LIE |
|
||||
ICS_DMA0_E;
|
||||
ICS_AERR | ICS_PERR | ICS_PIE | ICS_PLIE | ICS_PAIE | ICS_LIE |
|
||||
ICS_DMA0_E;
|
||||
writel(plx_intcsr_bits, priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
|
||||
|
||||
return 0;
|
||||
@@ -491,11 +492,11 @@ static int init_hpdi(struct comedi_device *dev)
|
||||
|
||||
/* setup dma descriptors so a link completes every 'transfer_size' bytes */
|
||||
static int setup_dma_descriptors(struct comedi_device *dev,
|
||||
unsigned int transfer_size)
|
||||
unsigned int transfer_size)
|
||||
{
|
||||
unsigned int buffer_index, buffer_offset;
|
||||
uint32_t next_bits = PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT |
|
||||
PLX_XFER_LOCAL_TO_PCI;
|
||||
PLX_XFER_LOCAL_TO_PCI;
|
||||
unsigned int i;
|
||||
|
||||
if (transfer_size > DMA_BUFFER_SIZE)
|
||||
@@ -506,26 +507,26 @@ static int setup_dma_descriptors(struct comedi_device *dev,
|
||||
|
||||
DEBUG_PRINT(" transfer_size %i\n", transfer_size);
|
||||
DEBUG_PRINT(" descriptors at 0x%lx\n",
|
||||
(unsigned long)priv(dev)->dma_desc_phys_addr);
|
||||
(unsigned long)priv(dev)->dma_desc_phys_addr);
|
||||
|
||||
buffer_offset = 0;
|
||||
buffer_index = 0;
|
||||
for (i = 0; i < NUM_DMA_DESCRIPTORS &&
|
||||
buffer_index < NUM_DMA_BUFFERS; i++) {
|
||||
buffer_index < NUM_DMA_BUFFERS; i++) {
|
||||
priv(dev)->dma_desc[i].pci_start_addr =
|
||||
cpu_to_le32(priv(dev)->
|
||||
dio_buffer_phys_addr[buffer_index] + buffer_offset);
|
||||
cpu_to_le32(priv(dev)->dio_buffer_phys_addr[buffer_index] +
|
||||
buffer_offset);
|
||||
priv(dev)->dma_desc[i].local_start_addr = cpu_to_le32(FIFO_REG);
|
||||
priv(dev)->dma_desc[i].transfer_size =
|
||||
cpu_to_le32(transfer_size);
|
||||
cpu_to_le32(transfer_size);
|
||||
priv(dev)->dma_desc[i].next =
|
||||
cpu_to_le32((priv(dev)->dma_desc_phys_addr + (i +
|
||||
1) *
|
||||
sizeof(priv(dev)->dma_desc[0])) | next_bits);
|
||||
cpu_to_le32((priv(dev)->dma_desc_phys_addr + (i +
|
||||
1) *
|
||||
sizeof(priv(dev)->dma_desc[0])) | next_bits);
|
||||
|
||||
priv(dev)->desc_dio_buffer[i] =
|
||||
priv(dev)->dio_buffer[buffer_index] +
|
||||
(buffer_offset / sizeof(uint32_t));
|
||||
priv(dev)->dio_buffer[buffer_index] +
|
||||
(buffer_offset / sizeof(uint32_t));
|
||||
|
||||
buffer_offset += transfer_size;
|
||||
if (transfer_size + buffer_offset > DMA_BUFFER_SIZE) {
|
||||
@@ -535,17 +536,18 @@ static int setup_dma_descriptors(struct comedi_device *dev,
|
||||
|
||||
DEBUG_PRINT(" desc %i\n", i);
|
||||
DEBUG_PRINT(" start addr virt 0x%p, phys 0x%lx\n",
|
||||
priv(dev)->desc_dio_buffer[i],
|
||||
(unsigned long)priv(dev)->dma_desc[i].pci_start_addr);
|
||||
priv(dev)->desc_dio_buffer[i],
|
||||
(unsigned long)priv(dev)->dma_desc[i].
|
||||
pci_start_addr);
|
||||
DEBUG_PRINT(" next 0x%lx\n",
|
||||
(unsigned long)priv(dev)->dma_desc[i].next);
|
||||
(unsigned long)priv(dev)->dma_desc[i].next);
|
||||
}
|
||||
priv(dev)->num_dma_descriptors = i;
|
||||
/* fix last descriptor to point back to first */
|
||||
priv(dev)->dma_desc[i - 1].next =
|
||||
cpu_to_le32(priv(dev)->dma_desc_phys_addr | next_bits);
|
||||
cpu_to_le32(priv(dev)->dma_desc_phys_addr | next_bits);
|
||||
DEBUG_PRINT(" desc %i next fixup 0x%lx\n", i - 1,
|
||||
(unsigned long)priv(dev)->dma_desc[i - 1].next);
|
||||
(unsigned long)priv(dev)->dma_desc[i - 1].next);
|
||||
|
||||
priv(dev)->block_size = transfer_size;
|
||||
|
||||
@@ -567,14 +569,15 @@ static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
for (i = 0; i < ARRAY_SIZE(hpdi_boards) && dev->board_ptr == NULL; i++) {
|
||||
do {
|
||||
pcidev = pci_get_subsys(PCI_VENDOR_ID_PLX,
|
||||
hpdi_boards[i].device_id, PCI_VENDOR_ID_PLX,
|
||||
hpdi_boards[i].subdevice_id, pcidev);
|
||||
hpdi_boards[i].device_id,
|
||||
PCI_VENDOR_ID_PLX,
|
||||
hpdi_boards[i].subdevice_id,
|
||||
pcidev);
|
||||
/* was a particular bus/slot requested? */
|
||||
if (it->options[0] || it->options[1]) {
|
||||
/* are we on the wrong bus/slot? */
|
||||
if (pcidev->bus->number != it->options[0] ||
|
||||
PCI_SLOT(pcidev->devfn) !=
|
||||
it->options[1])
|
||||
PCI_SLOT(pcidev->devfn) != it->options[1])
|
||||
continue;
|
||||
}
|
||||
if (pcidev) {
|
||||
@@ -590,11 +593,11 @@ static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
}
|
||||
|
||||
printk("gsc_hpdi: found %s on bus %i, slot %i\n", board(dev)->name,
|
||||
pcidev->bus->number, PCI_SLOT(pcidev->devfn));
|
||||
pcidev->bus->number, PCI_SLOT(pcidev->devfn));
|
||||
|
||||
if (comedi_pci_enable(pcidev, driver_hpdi.driver_name)) {
|
||||
printk(KERN_WARNING
|
||||
" failed enable PCI device and request regions\n");
|
||||
" failed enable PCI device and request regions\n");
|
||||
return -EIO;
|
||||
}
|
||||
pci_set_master(pcidev);
|
||||
@@ -603,15 +606,17 @@ static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
dev->board_name = board(dev)->name;
|
||||
|
||||
priv(dev)->plx9080_phys_iobase =
|
||||
pci_resource_start(pcidev, PLX9080_BADDRINDEX);
|
||||
pci_resource_start(pcidev, PLX9080_BADDRINDEX);
|
||||
priv(dev)->hpdi_phys_iobase =
|
||||
pci_resource_start(pcidev, HPDI_BADDRINDEX);
|
||||
pci_resource_start(pcidev, HPDI_BADDRINDEX);
|
||||
|
||||
/* remap, won't work with 2.0 kernels but who cares */
|
||||
priv(dev)->plx9080_iobase = ioremap(priv(dev)->plx9080_phys_iobase,
|
||||
pci_resource_len(pcidev, PLX9080_BADDRINDEX));
|
||||
priv(dev)->hpdi_iobase = ioremap(priv(dev)->hpdi_phys_iobase,
|
||||
pci_resource_len(pcidev, HPDI_BADDRINDEX));
|
||||
pci_resource_len(pcidev,
|
||||
PLX9080_BADDRINDEX));
|
||||
priv(dev)->hpdi_iobase =
|
||||
ioremap(priv(dev)->hpdi_phys_iobase,
|
||||
pci_resource_len(pcidev, HPDI_BADDRINDEX));
|
||||
if (!priv(dev)->plx9080_iobase || !priv(dev)->hpdi_iobase) {
|
||||
printk(" failed to remap io memory\n");
|
||||
return -ENOMEM;
|
||||
@@ -635,16 +640,18 @@ static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
/* alocate pci dma buffers */
|
||||
for (i = 0; i < NUM_DMA_BUFFERS; i++) {
|
||||
priv(dev)->dio_buffer[i] =
|
||||
pci_alloc_consistent(priv(dev)->hw_dev, DMA_BUFFER_SIZE,
|
||||
&priv(dev)->dio_buffer_phys_addr[i]);
|
||||
pci_alloc_consistent(priv(dev)->hw_dev, DMA_BUFFER_SIZE,
|
||||
&priv(dev)->dio_buffer_phys_addr[i]);
|
||||
DEBUG_PRINT("dio_buffer at virt 0x%p, phys 0x%lx\n",
|
||||
priv(dev)->dio_buffer[i],
|
||||
(unsigned long)priv(dev)->dio_buffer_phys_addr[i]);
|
||||
priv(dev)->dio_buffer[i],
|
||||
(unsigned long)priv(dev)->dio_buffer_phys_addr[i]);
|
||||
}
|
||||
/* allocate dma descriptors */
|
||||
priv(dev)->dma_desc = pci_alloc_consistent(priv(dev)->hw_dev,
|
||||
sizeof(struct plx_dma_desc) * NUM_DMA_DESCRIPTORS,
|
||||
&priv(dev)->dma_desc_phys_addr);
|
||||
sizeof(struct plx_dma_desc) *
|
||||
NUM_DMA_DESCRIPTORS,
|
||||
&priv(dev)->
|
||||
dma_desc_phys_addr);
|
||||
if (priv(dev)->dma_desc_phys_addr & 0xf) {
|
||||
printk(" dma descriptors not quad-word aligned (bug)\n");
|
||||
return -EIO;
|
||||
@@ -681,18 +688,21 @@ static int hpdi_detach(struct comedi_device *dev)
|
||||
for (i = 0; i < NUM_DMA_BUFFERS; i++) {
|
||||
if (priv(dev)->dio_buffer[i])
|
||||
pci_free_consistent(priv(dev)->hw_dev,
|
||||
DMA_BUFFER_SIZE,
|
||||
priv(dev)->dio_buffer[i],
|
||||
priv(dev)->
|
||||
dio_buffer_phys_addr[i]);
|
||||
DMA_BUFFER_SIZE,
|
||||
priv(dev)->
|
||||
dio_buffer[i],
|
||||
priv
|
||||
(dev)->dio_buffer_phys_addr
|
||||
[i]);
|
||||
}
|
||||
/* free dma descriptors */
|
||||
if (priv(dev)->dma_desc)
|
||||
pci_free_consistent(priv(dev)->hw_dev,
|
||||
sizeof(struct plx_dma_desc) *
|
||||
NUM_DMA_DESCRIPTORS,
|
||||
priv(dev)->dma_desc,
|
||||
priv(dev)->dma_desc_phys_addr);
|
||||
sizeof(struct plx_dma_desc)
|
||||
* NUM_DMA_DESCRIPTORS,
|
||||
priv(dev)->dma_desc,
|
||||
priv(dev)->
|
||||
dma_desc_phys_addr);
|
||||
if (priv(dev)->hpdi_phys_iobase) {
|
||||
comedi_pci_disable(priv(dev)->hw_dev);
|
||||
}
|
||||
@@ -719,7 +729,7 @@ static int dio_config_block_size(struct comedi_device *dev, unsigned int *data)
|
||||
}
|
||||
|
||||
static int di_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd)
|
||||
struct comedi_cmd *cmd)
|
||||
{
|
||||
int err = 0;
|
||||
int tmp;
|
||||
@@ -805,7 +815,7 @@ static int di_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
if (CR_CHAN(cmd->chanlist[i]) != i) {
|
||||
/* XXX could support 8 channels or 16 channels */
|
||||
comedi_error(dev,
|
||||
"chanlist must be channels 0 to 31 in order");
|
||||
"chanlist must be channels 0 to 31 in order");
|
||||
err++;
|
||||
break;
|
||||
}
|
||||
@@ -819,7 +829,7 @@ static int di_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
}
|
||||
|
||||
static int hpdi_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd)
|
||||
struct comedi_cmd *cmd)
|
||||
{
|
||||
if (priv(dev)->dio_config_output) {
|
||||
return -EINVAL;
|
||||
@@ -828,10 +838,10 @@ static int hpdi_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
}
|
||||
|
||||
static inline void hpdi_writel(struct comedi_device *dev, uint32_t bits,
|
||||
unsigned int offset)
|
||||
unsigned int offset)
|
||||
{
|
||||
writel(bits | priv(dev)->bits[offset / sizeof(uint32_t)],
|
||||
priv(dev)->hpdi_iobase + offset);
|
||||
priv(dev)->hpdi_iobase + offset);
|
||||
}
|
||||
|
||||
static int di_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
@@ -857,16 +867,16 @@ static int di_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
writel(0, priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG);
|
||||
writel(0, priv(dev)->plx9080_iobase + PLX_DMA0_LOCAL_ADDRESS_REG);
|
||||
/* give location of first dma descriptor */
|
||||
bits = priv(dev)->
|
||||
dma_desc_phys_addr | PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT |
|
||||
PLX_XFER_LOCAL_TO_PCI;
|
||||
bits =
|
||||
priv(dev)->dma_desc_phys_addr | PLX_DESC_IN_PCI_BIT |
|
||||
PLX_INTR_TERM_COUNT | PLX_XFER_LOCAL_TO_PCI;
|
||||
writel(bits, priv(dev)->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG);
|
||||
|
||||
/* spinlock for plx dma control/status reg */
|
||||
spin_lock_irqsave(&dev->spinlock, flags);
|
||||
/* enable dma transfer */
|
||||
writeb(PLX_DMA_EN_BIT | PLX_DMA_START_BIT | PLX_CLEAR_DMA_INTR_BIT,
|
||||
priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
|
||||
priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
|
||||
spin_unlock_irqrestore(&dev->spinlock, flags);
|
||||
|
||||
if (cmd->stop_src == TRIG_COUNT)
|
||||
@@ -876,10 +886,10 @@ static int di_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
|
||||
/* clear over/under run status flags */
|
||||
writel(RX_UNDERRUN_BIT | RX_OVERRUN_BIT,
|
||||
priv(dev)->hpdi_iobase + BOARD_STATUS_REG);
|
||||
priv(dev)->hpdi_iobase + BOARD_STATUS_REG);
|
||||
/* enable interrupts */
|
||||
writel(intr_bit(RX_FULL_INTR),
|
||||
priv(dev)->hpdi_iobase + INTERRUPT_CONTROL_REG);
|
||||
priv(dev)->hpdi_iobase + INTERRUPT_CONTROL_REG);
|
||||
|
||||
DEBUG_PRINT("hpdi: starting rx\n");
|
||||
hpdi_writel(dev, RX_ENABLE_BIT, BOARD_CONTROL_REG);
|
||||
@@ -905,22 +915,21 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel)
|
||||
|
||||
if (channel)
|
||||
pci_addr_reg =
|
||||
priv(dev)->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG;
|
||||
priv(dev)->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG;
|
||||
else
|
||||
pci_addr_reg =
|
||||
priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG;
|
||||
priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG;
|
||||
|
||||
/* loop until we have read all the full buffers */
|
||||
j = 0;
|
||||
for (next_transfer_addr = readl(pci_addr_reg);
|
||||
(next_transfer_addr <
|
||||
le32_to_cpu(priv(dev)->dma_desc[priv(dev)->
|
||||
dma_desc_index].pci_start_addr)
|
||||
|| next_transfer_addr >=
|
||||
le32_to_cpu(priv(dev)->dma_desc[priv(dev)->
|
||||
dma_desc_index].pci_start_addr) +
|
||||
priv(dev)->block_size)
|
||||
&& j < priv(dev)->num_dma_descriptors; j++) {
|
||||
(next_transfer_addr <
|
||||
le32_to_cpu(priv(dev)->dma_desc[priv(dev)->dma_desc_index].
|
||||
pci_start_addr)
|
||||
|| next_transfer_addr >=
|
||||
le32_to_cpu(priv(dev)->dma_desc[priv(dev)->dma_desc_index].
|
||||
pci_start_addr) + priv(dev)->block_size)
|
||||
&& j < priv(dev)->num_dma_descriptors; j++) {
|
||||
/* transfer data from dma buffer to comedi buffer */
|
||||
num_samples = priv(dev)->block_size / sizeof(uint32_t);
|
||||
if (async->cmd.stop_src == TRIG_COUNT) {
|
||||
@@ -929,13 +938,15 @@ static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel)
|
||||
priv(dev)->dio_count -= num_samples;
|
||||
}
|
||||
cfc_write_array_to_buffer(dev->read_subdev,
|
||||
priv(dev)->desc_dio_buffer[priv(dev)->dma_desc_index],
|
||||
num_samples * sizeof(uint32_t));
|
||||
priv(dev)->desc_dio_buffer[priv(dev)->
|
||||
dma_desc_index],
|
||||
num_samples * sizeof(uint32_t));
|
||||
priv(dev)->dma_desc_index++;
|
||||
priv(dev)->dma_desc_index %= priv(dev)->num_dma_descriptors;
|
||||
|
||||
DEBUG_PRINT("next desc addr 0x%lx\n", (unsigned long)
|
||||
priv(dev)->dma_desc[priv(dev)->dma_desc_index].next);
|
||||
priv(dev)->dma_desc[priv(dev)->dma_desc_index].
|
||||
next);
|
||||
DEBUG_PRINT("pci addr reg 0x%x\n", next_transfer_addr);
|
||||
}
|
||||
/* XXX check for buffer overrun somehow */
|
||||
@@ -969,14 +980,14 @@ static irqreturn_t handle_interrupt(int irq, void *d)
|
||||
if (hpdi_intr_status) {
|
||||
DEBUG_PRINT("hpdi: intr status 0x%x, ", hpdi_intr_status);
|
||||
writel(hpdi_intr_status,
|
||||
priv(dev)->hpdi_iobase + INTERRUPT_STATUS_REG);
|
||||
priv(dev)->hpdi_iobase + INTERRUPT_STATUS_REG);
|
||||
}
|
||||
/* spin lock makes sure noone else changes plx dma control reg */
|
||||
spin_lock_irqsave(&dev->spinlock, flags);
|
||||
dma0_status = readb(priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
|
||||
if (plx_status & ICS_DMA0_A) { /* dma chan 0 interrupt */
|
||||
writeb((dma0_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT,
|
||||
priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
|
||||
priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
|
||||
|
||||
DEBUG_PRINT("dma0 status 0x%x\n", dma0_status);
|
||||
if (dma0_status & PLX_DMA_EN_BIT) {
|
||||
@@ -989,10 +1000,9 @@ static irqreturn_t handle_interrupt(int irq, void *d)
|
||||
/* spin lock makes sure noone else changes plx dma control reg */
|
||||
spin_lock_irqsave(&dev->spinlock, flags);
|
||||
dma1_status = readb(priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG);
|
||||
if (plx_status & ICS_DMA1_A) /* XXX */
|
||||
{ /* dma chan 1 interrupt */
|
||||
if (plx_status & ICS_DMA1_A) { /* XXX *//* dma chan 1 interrupt */
|
||||
writeb((dma1_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT,
|
||||
priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG);
|
||||
priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG);
|
||||
DEBUG_PRINT("dma1 status 0x%x\n", dma1_status);
|
||||
|
||||
DEBUG_PRINT(" cleared dma ch1 interrupt\n");
|
||||
@@ -1010,8 +1020,8 @@ static irqreturn_t handle_interrupt(int irq, void *d)
|
||||
comedi_error(dev, "rx fifo overrun");
|
||||
async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
|
||||
DEBUG_PRINT("dma0_status 0x%x\n",
|
||||
(int)readb(priv(dev)->plx9080_iobase +
|
||||
PLX_DMA0_CS_REG));
|
||||
(int)readb(priv(dev)->plx9080_iobase +
|
||||
PLX_DMA0_CS_REG));
|
||||
}
|
||||
|
||||
if (hpdi_board_status & RX_UNDERRUN_BIT) {
|
||||
|
||||
@@ -110,11 +110,11 @@ There are 4 x 12-bit Analogue Outputs. Ranges : 5V, 10V, +/-5V, +/-10V
|
||||
|
||||
/* Define analogue range */
|
||||
static const struct comedi_lrange range_analog = { 4, {
|
||||
UNI_RANGE(5),
|
||||
UNI_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(10)
|
||||
}
|
||||
UNI_RANGE(5),
|
||||
UNI_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(10)
|
||||
}
|
||||
};
|
||||
|
||||
static const char range_codes_analog[] = { 0x00, 0x20, 0x10, 0x30 };
|
||||
@@ -124,7 +124,8 @@ static const char range_codes_analog[] = { 0x00, 0x20, 0x10, 0x30 };
|
||||
Forward declarations
|
||||
==============================================================================
|
||||
*/
|
||||
static int icp_multi_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int icp_multi_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int icp_multi_detach(struct comedi_device *dev);
|
||||
|
||||
/*
|
||||
@@ -155,33 +156,33 @@ struct boardtype {
|
||||
|
||||
static const struct boardtype boardtypes[] = {
|
||||
{"icp_multi", /* Driver name */
|
||||
DEVICE_ID, /* PCI device ID */
|
||||
IORANGE_ICP_MULTI, /* I/O range length */
|
||||
1, /* 1=Card supports interrupts */
|
||||
TYPE_ICP_MULTI, /* Card type = ICP MULTI */
|
||||
16, /* Num of A/D channels */
|
||||
8, /* Num of A/D channels in diff mode */
|
||||
4, /* Num of D/A channels */
|
||||
16, /* Num of digital inputs */
|
||||
8, /* Num of digital outputs */
|
||||
4, /* Num of counters */
|
||||
0x0fff, /* Resolution of A/D */
|
||||
0x0fff, /* Resolution of D/A */
|
||||
&range_analog, /* Rangelist for A/D */
|
||||
range_codes_analog, /* Range codes for programming */
|
||||
&range_analog}, /* Rangelist for D/A */
|
||||
DEVICE_ID, /* PCI device ID */
|
||||
IORANGE_ICP_MULTI, /* I/O range length */
|
||||
1, /* 1=Card supports interrupts */
|
||||
TYPE_ICP_MULTI, /* Card type = ICP MULTI */
|
||||
16, /* Num of A/D channels */
|
||||
8, /* Num of A/D channels in diff mode */
|
||||
4, /* Num of D/A channels */
|
||||
16, /* Num of digital inputs */
|
||||
8, /* Num of digital outputs */
|
||||
4, /* Num of counters */
|
||||
0x0fff, /* Resolution of A/D */
|
||||
0x0fff, /* Resolution of D/A */
|
||||
&range_analog, /* Rangelist for A/D */
|
||||
range_codes_analog, /* Range codes for programming */
|
||||
&range_analog}, /* Rangelist for D/A */
|
||||
};
|
||||
|
||||
#define n_boardtypes (sizeof(boardtypes)/sizeof(struct boardtype))
|
||||
|
||||
static struct comedi_driver driver_icp_multi = {
|
||||
driver_name:"icp_multi",
|
||||
module : THIS_MODULE,
|
||||
attach : icp_multi_attach,
|
||||
detach : icp_multi_detach,
|
||||
num_names : n_boardtypes,
|
||||
board_name : &boardtypes[0].name,
|
||||
offset : sizeof(struct boardtype),
|
||||
driver_name:"icp_multi",
|
||||
module:THIS_MODULE,
|
||||
attach:icp_multi_attach,
|
||||
detach:icp_multi_detach,
|
||||
num_names:n_boardtypes,
|
||||
board_name:&boardtypes[0].name,
|
||||
offset:sizeof(struct boardtype),
|
||||
};
|
||||
|
||||
COMEDI_INITCLEANUP(driver_icp_multi);
|
||||
@@ -199,9 +200,9 @@ struct icp_multi_private {
|
||||
unsigned char act_chanlist_len; /* len of scanlist */
|
||||
unsigned char act_chanlist_pos; /* actual position in MUX list */
|
||||
unsigned int *ai_chanlist; /* actaul chanlist */
|
||||
short *ai_data; /* data buffer */
|
||||
short *ai_data; /* data buffer */
|
||||
short ao_data[4]; /* data output buffer */
|
||||
short di_data; /* Digital input data */
|
||||
short di_data; /* Digital input data */
|
||||
unsigned int do_data; /* Remember digital output data */
|
||||
};
|
||||
|
||||
@@ -215,11 +216,13 @@ struct icp_multi_private {
|
||||
*/
|
||||
|
||||
#if 0
|
||||
static int check_channel_list(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
unsigned int *chanlist, unsigned int n_chan);
|
||||
static int check_channel_list(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
unsigned int *chanlist, unsigned int n_chan);
|
||||
#endif
|
||||
static void setup_channel_list(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
unsigned int *chanlist, unsigned int n_chan);
|
||||
static void setup_channel_list(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
unsigned int *chanlist, unsigned int n_chan);
|
||||
static int icp_multi_reset(struct comedi_device *dev);
|
||||
|
||||
/*
|
||||
@@ -246,8 +249,9 @@ static int icp_multi_reset(struct comedi_device *dev);
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
static int icp_multi_insn_read_ai(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int icp_multi_insn_read_ai(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int n, timeout;
|
||||
|
||||
@@ -267,42 +271,42 @@ static int icp_multi_insn_read_ai(struct comedi_device *dev, struct comedi_subde
|
||||
|
||||
#ifdef ICP_MULTI_EXTDEBUG
|
||||
printk("icp_multi A ST=%4x IO=%p\n",
|
||||
readw(devpriv->io_addr + ICP_MULTI_ADC_CSR),
|
||||
devpriv->io_addr + ICP_MULTI_ADC_CSR);
|
||||
readw(devpriv->io_addr + ICP_MULTI_ADC_CSR),
|
||||
devpriv->io_addr + ICP_MULTI_ADC_CSR);
|
||||
#endif
|
||||
|
||||
for (n = 0; n < insn->n; n++) {
|
||||
/* Set start ADC bit */
|
||||
devpriv->AdcCmdStatus |= ADC_ST;
|
||||
writew(devpriv->AdcCmdStatus,
|
||||
devpriv->io_addr + ICP_MULTI_ADC_CSR);
|
||||
devpriv->io_addr + ICP_MULTI_ADC_CSR);
|
||||
devpriv->AdcCmdStatus &= ~ADC_ST;
|
||||
|
||||
#ifdef ICP_MULTI_EXTDEBUG
|
||||
printk("icp multi B n=%d ST=%4x\n", n,
|
||||
readw(devpriv->io_addr + ICP_MULTI_ADC_CSR));
|
||||
readw(devpriv->io_addr + ICP_MULTI_ADC_CSR));
|
||||
#endif
|
||||
|
||||
udelay(1);
|
||||
|
||||
#ifdef ICP_MULTI_EXTDEBUG
|
||||
printk("icp multi C n=%d ST=%4x\n", n,
|
||||
readw(devpriv->io_addr + ICP_MULTI_ADC_CSR));
|
||||
readw(devpriv->io_addr + ICP_MULTI_ADC_CSR));
|
||||
#endif
|
||||
|
||||
/* Wait for conversion to complete, or get fed up waiting */
|
||||
timeout = 100;
|
||||
while (timeout--) {
|
||||
if (!(readw(devpriv->io_addr +
|
||||
ICP_MULTI_ADC_CSR) & ADC_BSY))
|
||||
ICP_MULTI_ADC_CSR) & ADC_BSY))
|
||||
goto conv_finish;
|
||||
|
||||
#ifdef ICP_MULTI_EXTDEBUG
|
||||
if (!(timeout % 10))
|
||||
printk("icp multi D n=%d tm=%d ST=%4x\n", n,
|
||||
timeout,
|
||||
readw(devpriv->io_addr +
|
||||
ICP_MULTI_ADC_CSR));
|
||||
timeout,
|
||||
readw(devpriv->io_addr +
|
||||
ICP_MULTI_ADC_CSR));
|
||||
#endif
|
||||
|
||||
udelay(1);
|
||||
@@ -318,19 +322,21 @@ static int icp_multi_insn_read_ai(struct comedi_device *dev, struct comedi_subde
|
||||
/* Clear interrupt status */
|
||||
devpriv->IntStatus |= ADC_READY;
|
||||
writew(devpriv->IntStatus,
|
||||
devpriv->io_addr + ICP_MULTI_INT_STAT);
|
||||
devpriv->io_addr + ICP_MULTI_INT_STAT);
|
||||
|
||||
/* Clear data received */
|
||||
data[n] = 0;
|
||||
|
||||
#ifdef ICP_MULTI_EXTDEBUG
|
||||
printk("icp multi EDBG: END: icp_multi_insn_read_ai(...) n=%d\n", n);
|
||||
printk
|
||||
("icp multi EDBG: END: icp_multi_insn_read_ai(...) n=%d\n",
|
||||
n);
|
||||
#endif
|
||||
return -ETIME;
|
||||
|
||||
conv_finish:
|
||||
conv_finish:
|
||||
data[n] =
|
||||
(readw(devpriv->io_addr + ICP_MULTI_AI) >> 4) & 0x0fff;
|
||||
(readw(devpriv->io_addr + ICP_MULTI_AI) >> 4) & 0x0fff;
|
||||
}
|
||||
|
||||
/* Disable interrupt */
|
||||
@@ -365,8 +371,9 @@ static int icp_multi_insn_read_ai(struct comedi_device *dev, struct comedi_subde
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
static int icp_multi_insn_write_ao(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int icp_multi_insn_write_ao(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int n, chan, range, timeout;
|
||||
|
||||
@@ -401,15 +408,15 @@ static int icp_multi_insn_write_ao(struct comedi_device *dev, struct comedi_subd
|
||||
timeout = 100;
|
||||
while (timeout--) {
|
||||
if (!(readw(devpriv->io_addr +
|
||||
ICP_MULTI_DAC_CSR) & DAC_BSY))
|
||||
ICP_MULTI_DAC_CSR) & DAC_BSY))
|
||||
goto dac_ready;
|
||||
|
||||
#ifdef ICP_MULTI_EXTDEBUG
|
||||
if (!(timeout % 10))
|
||||
printk("icp multi A n=%d tm=%d ST=%4x\n", n,
|
||||
timeout,
|
||||
readw(devpriv->io_addr +
|
||||
ICP_MULTI_DAC_CSR));
|
||||
timeout,
|
||||
readw(devpriv->io_addr +
|
||||
ICP_MULTI_DAC_CSR));
|
||||
#endif
|
||||
|
||||
udelay(1);
|
||||
@@ -425,24 +432,26 @@ static int icp_multi_insn_write_ao(struct comedi_device *dev, struct comedi_subd
|
||||
/* Clear interrupt status */
|
||||
devpriv->IntStatus |= DAC_READY;
|
||||
writew(devpriv->IntStatus,
|
||||
devpriv->io_addr + ICP_MULTI_INT_STAT);
|
||||
devpriv->io_addr + ICP_MULTI_INT_STAT);
|
||||
|
||||
/* Clear data received */
|
||||
devpriv->ao_data[chan] = 0;
|
||||
|
||||
#ifdef ICP_MULTI_EXTDEBUG
|
||||
printk("icp multi EDBG: END: icp_multi_insn_write_ao(...) n=%d\n", n);
|
||||
printk
|
||||
("icp multi EDBG: END: icp_multi_insn_write_ao(...) n=%d\n",
|
||||
n);
|
||||
#endif
|
||||
return -ETIME;
|
||||
|
||||
dac_ready:
|
||||
dac_ready:
|
||||
/* Write data to analogue output data register */
|
||||
writew(data[n], devpriv->io_addr + ICP_MULTI_AO);
|
||||
|
||||
/* Set DAC_ST bit to write the data to selected channel */
|
||||
devpriv->DacCmdStatus |= DAC_ST;
|
||||
writew(devpriv->DacCmdStatus,
|
||||
devpriv->io_addr + ICP_MULTI_DAC_CSR);
|
||||
devpriv->io_addr + ICP_MULTI_DAC_CSR);
|
||||
devpriv->DacCmdStatus &= ~DAC_ST;
|
||||
|
||||
/* Save analogue output data */
|
||||
@@ -473,8 +482,9 @@ static int icp_multi_insn_write_ao(struct comedi_device *dev, struct comedi_subd
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
static int icp_multi_insn_read_ao(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int icp_multi_insn_read_ao(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int n, chan;
|
||||
|
||||
@@ -506,8 +516,9 @@ static int icp_multi_insn_read_ao(struct comedi_device *dev, struct comedi_subde
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
static int icp_multi_insn_bits_di(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int icp_multi_insn_bits_di(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
data[1] = readw(devpriv->io_addr + ICP_MULTI_DI);
|
||||
|
||||
@@ -532,8 +543,9 @@ static int icp_multi_insn_bits_di(struct comedi_device *dev, struct comedi_subde
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
static int icp_multi_insn_bits_do(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int icp_multi_insn_bits_do(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
#ifdef ICP_MULTI_EXTDEBUG
|
||||
printk("icp multi EDBG: BGN: icp_multi_insn_bits_do(...)\n");
|
||||
@@ -574,8 +586,9 @@ static int icp_multi_insn_bits_do(struct comedi_device *dev, struct comedi_subde
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
static int icp_multi_insn_read_ctr(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int icp_multi_insn_read_ctr(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -598,8 +611,10 @@ static int icp_multi_insn_read_ctr(struct comedi_device *dev, struct comedi_subd
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
static int icp_multi_insn_write_ctr(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int icp_multi_insn_write_ctr(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -626,7 +641,7 @@ static irqreturn_t interrupt_service_icp_multi(int irq, void *d)
|
||||
|
||||
#ifdef ICP_MULTI_EXTDEBUG
|
||||
printk("icp multi EDBG: BGN: interrupt_service_icp_multi(%d,...)\n",
|
||||
irq);
|
||||
irq);
|
||||
#endif
|
||||
|
||||
/* Is this interrupt from our board? */
|
||||
@@ -637,7 +652,7 @@ static irqreturn_t interrupt_service_icp_multi(int irq, void *d)
|
||||
|
||||
#ifdef ICP_MULTI_EXTDEBUG
|
||||
printk("icp multi EDBG: interrupt_service_icp_multi() ST: %4x\n",
|
||||
readw(devpriv->io_addr + ICP_MULTI_INT_STAT));
|
||||
readw(devpriv->io_addr + ICP_MULTI_INT_STAT));
|
||||
#endif
|
||||
|
||||
/* Determine which interrupt is active & handle it */
|
||||
@@ -690,8 +705,9 @@ static irqreturn_t interrupt_service_icp_multi(int irq, void *d)
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
static int check_channel_list(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
unsigned int *chanlist, unsigned int n_chan)
|
||||
static int check_channel_list(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
unsigned int *chanlist, unsigned int n_chan)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
@@ -709,13 +725,13 @@ static int check_channel_list(struct comedi_device *dev, struct comedi_subdevice
|
||||
if (CR_AREF(chanlist[i]) == AREF_DIFF) {
|
||||
if (CR_CHAN(chanlist[i]) > this_board->n_aichand) {
|
||||
comedi_error(dev,
|
||||
"Incorrect differential ai channel number");
|
||||
"Incorrect differential ai channel number");
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (CR_CHAN(chanlist[i]) > this_board->n_aichan) {
|
||||
comedi_error(dev,
|
||||
"Incorrect ai channel number");
|
||||
"Incorrect ai channel number");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -744,8 +760,9 @@ static int check_channel_list(struct comedi_device *dev, struct comedi_subdevice
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
static void setup_channel_list(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
unsigned int *chanlist, unsigned int n_chan)
|
||||
static void setup_channel_list(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
unsigned int *chanlist, unsigned int n_chan)
|
||||
{
|
||||
unsigned int i, range, chanprog;
|
||||
unsigned int diff;
|
||||
@@ -788,11 +805,11 @@ static void setup_channel_list(struct comedi_device *dev, struct comedi_subdevic
|
||||
|
||||
/* Output channel, range, mode to ICP Multi */
|
||||
writew(devpriv->AdcCmdStatus,
|
||||
devpriv->io_addr + ICP_MULTI_ADC_CSR);
|
||||
devpriv->io_addr + ICP_MULTI_ADC_CSR);
|
||||
|
||||
#ifdef ICP_MULTI_EXTDEBUG
|
||||
printk("GS: %2d. [%4x]=%4x %4x\n", i, chanprog, range,
|
||||
devpriv->act_chanlist[i]);
|
||||
devpriv->act_chanlist[i]);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -840,7 +857,7 @@ static int icp_multi_reset(struct comedi_device *dev)
|
||||
|
||||
/* Output to command / status register */
|
||||
writew(devpriv->DacCmdStatus,
|
||||
devpriv->io_addr + ICP_MULTI_DAC_CSR);
|
||||
devpriv->io_addr + ICP_MULTI_DAC_CSR);
|
||||
|
||||
/* Delay to allow DAC time to recover */
|
||||
udelay(1);
|
||||
@@ -871,7 +888,8 @@ static int icp_multi_reset(struct comedi_device *dev)
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
static int icp_multi_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
static int icp_multi_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it)
|
||||
{
|
||||
struct comedi_subdevice *s;
|
||||
int ret, subdev, n_subdevices;
|
||||
@@ -891,15 +909,15 @@ static int icp_multi_attach(struct comedi_device *dev, struct comedi_devconfig *
|
||||
if (pci_list_builded++ == 0) {
|
||||
pci_card_list_init(PCI_VENDOR_ID_ICP,
|
||||
#ifdef ICP_MULTI_EXTDEBUG
|
||||
1
|
||||
1
|
||||
#else
|
||||
0
|
||||
0
|
||||
#endif
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
printk("Anne's comedi%d: icp_multi: board=%s", dev->minor,
|
||||
this_board->name);
|
||||
this_board->name);
|
||||
|
||||
card = select_and_alloc_pci_card(PCI_VENDOR_ID_ICP,
|
||||
this_board->device_id, it->options[0],
|
||||
@@ -911,7 +929,7 @@ static int icp_multi_attach(struct comedi_device *dev, struct comedi_devconfig *
|
||||
devpriv->card = card;
|
||||
|
||||
if ((pci_card_data(card, &pci_bus, &pci_slot, &pci_func, &io_addr[0],
|
||||
&irq)) < 0) {
|
||||
&irq)) < 0) {
|
||||
printk(" - Can't get configuration data!\n");
|
||||
return -EIO;
|
||||
}
|
||||
@@ -920,7 +938,7 @@ static int icp_multi_attach(struct comedi_device *dev, struct comedi_devconfig *
|
||||
devpriv->phys_iobase = iobase;
|
||||
|
||||
printk(", b:s:f=%d:%d:%d, io=0x%8llx \n", pci_bus, pci_slot, pci_func,
|
||||
(unsigned long long)iobase);
|
||||
(unsigned long long)iobase);
|
||||
|
||||
devpriv->io_addr = ioremap(iobase, ICP_MULTI_SIZE);
|
||||
|
||||
@@ -930,7 +948,7 @@ static int icp_multi_attach(struct comedi_device *dev, struct comedi_devconfig *
|
||||
}
|
||||
#ifdef ICP_MULTI_EXTDEBUG
|
||||
printk("0x%08llx mapped to %p, ", (unsigned long long)iobase,
|
||||
devpriv->io_addr);
|
||||
devpriv->io_addr);
|
||||
#endif
|
||||
|
||||
dev->board_name = this_board->name;
|
||||
@@ -957,7 +975,9 @@ static int icp_multi_attach(struct comedi_device *dev, struct comedi_devconfig *
|
||||
if (irq) {
|
||||
if (request_irq(irq, interrupt_service_icp_multi,
|
||||
IRQF_SHARED, "Inova Icp Multi", dev)) {
|
||||
printk(", unable to allocate IRQ %u, DISABLING IT", irq);
|
||||
printk
|
||||
(", unable to allocate IRQ %u, DISABLING IT",
|
||||
irq);
|
||||
irq = 0; /* Can't use IRQ */
|
||||
} else
|
||||
printk(", irq=%u", irq);
|
||||
|
||||
@@ -36,20 +36,26 @@ struct pcilst_struct *inova_devices;
|
||||
static void pci_card_list_init(unsigned short pci_vendor, char display);
|
||||
static void pci_card_list_cleanup(unsigned short pci_vendor);
|
||||
static struct pcilst_struct *find_free_pci_card_by_device(unsigned short
|
||||
vendor_id, unsigned short device_id);
|
||||
vendor_id,
|
||||
unsigned short
|
||||
device_id);
|
||||
static int 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);
|
||||
unsigned short device_id,
|
||||
unsigned short pci_bus,
|
||||
unsigned short pci_slot,
|
||||
struct pcilst_struct **card);
|
||||
static struct pcilst_struct *select_and_alloc_pci_card(unsigned short vendor_id,
|
||||
unsigned short device_id, unsigned short pci_bus,
|
||||
unsigned short pci_slot);
|
||||
unsigned short device_id,
|
||||
unsigned short pci_bus,
|
||||
unsigned short pci_slot);
|
||||
|
||||
static int pci_card_alloc(struct pcilst_struct *amcc);
|
||||
static int pci_card_free(struct pcilst_struct *amcc);
|
||||
static void pci_card_list_display(void);
|
||||
static int 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);
|
||||
unsigned char *pci_bus, unsigned char *pci_slot,
|
||||
unsigned char *pci_func, resource_size_t * io_addr,
|
||||
unsigned int *irq);
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
@@ -64,12 +70,13 @@ static void pci_card_list_init(unsigned short pci_vendor, char display)
|
||||
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)) {
|
||||
pcidev != NULL;
|
||||
pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
|
||||
if (pcidev->vendor == pci_vendor) {
|
||||
inova = kmalloc(sizeof(*inova), GFP_KERNEL);
|
||||
if (!inova) {
|
||||
printk("icp_multi: pci_card_list_init: allocation failed\n");
|
||||
printk
|
||||
("icp_multi: pci_card_list_init: allocation failed\n");
|
||||
pci_dev_put(pcidev);
|
||||
break;
|
||||
}
|
||||
@@ -93,7 +100,7 @@ static void pci_card_list_init(unsigned short pci_vendor, char display)
|
||||
* pci_card_alloc. */
|
||||
for (i = 0; i < 5; i++)
|
||||
inova->io_addr[i] =
|
||||
pci_resource_start(pcidev, i);
|
||||
pci_resource_start(pcidev, i);
|
||||
inova->irq = pcidev->irq;
|
||||
}
|
||||
}
|
||||
@@ -120,14 +127,16 @@ static void pci_card_list_cleanup(unsigned short pci_vendor)
|
||||
/****************************************************************************/
|
||||
/* find first unused card with this device_id */
|
||||
static struct pcilst_struct *find_free_pci_card_by_device(unsigned short
|
||||
vendor_id, unsigned short device_id)
|
||||
vendor_id,
|
||||
unsigned short
|
||||
device_id)
|
||||
{
|
||||
struct pcilst_struct *inova, *next;
|
||||
|
||||
for (inova = inova_devices; inova; inova = next) {
|
||||
next = inova->next;
|
||||
if ((!inova->used) && (inova->device == device_id)
|
||||
&& (inova->vendor == vendor_id))
|
||||
&& (inova->vendor == vendor_id))
|
||||
return inova;
|
||||
|
||||
}
|
||||
@@ -138,8 +147,10 @@ static struct pcilst_struct *find_free_pci_card_by_device(unsigned short
|
||||
/****************************************************************************/
|
||||
/* find card on requested position */
|
||||
static int 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)
|
||||
unsigned short device_id,
|
||||
unsigned short pci_bus,
|
||||
unsigned short pci_slot,
|
||||
struct pcilst_struct **card)
|
||||
{
|
||||
struct pcilst_struct *inova, *next;
|
||||
|
||||
@@ -147,8 +158,8 @@ static int find_free_pci_card_by_position(unsigned short vendor_id,
|
||||
for (inova = inova_devices; inova; inova = next) {
|
||||
next = inova->next;
|
||||
if ((inova->vendor == vendor_id) && (inova->device == device_id)
|
||||
&& (inova->pci_bus == pci_bus)
|
||||
&& (inova->pci_slot == pci_slot)) {
|
||||
&& (inova->pci_bus == pci_bus)
|
||||
&& (inova->pci_slot == pci_slot)) {
|
||||
if (!(inova->used)) {
|
||||
*card = inova;
|
||||
return 0; /* ok, card is found */
|
||||
@@ -211,7 +222,13 @@ static void pci_card_list_display(void)
|
||||
|
||||
for (inova = inova_devices; inova; inova = next) {
|
||||
next = inova->next;
|
||||
printk("%2d %2d %2d 0x%4x 0x%4x 0x%8llx 0x%8llx %2u %2d\n", inova->pci_bus, inova->pci_slot, inova->pci_func, inova->vendor, inova->device, (unsigned long long)inova->io_addr[0], (unsigned long long)inova->io_addr[2], inova->irq, inova->used);
|
||||
printk
|
||||
("%2d %2d %2d 0x%4x 0x%4x 0x%8llx 0x%8llx %2u %2d\n",
|
||||
inova->pci_bus, inova->pci_slot, inova->pci_func,
|
||||
inova->vendor, inova->device,
|
||||
(unsigned long long)inova->io_addr[0],
|
||||
(unsigned long long)inova->io_addr[2], inova->irq,
|
||||
inova->used);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -219,8 +236,9 @@ static void pci_card_list_display(void)
|
||||
/****************************************************************************/
|
||||
/* return all card information for driver */
|
||||
static int pci_card_data(struct pcilst_struct *inova,
|
||||
unsigned char *pci_bus, unsigned char *pci_slot,
|
||||
unsigned char *pci_func, resource_size_t * io_addr, unsigned int *irq)
|
||||
unsigned char *pci_bus, unsigned char *pci_slot,
|
||||
unsigned char *pci_func, resource_size_t * io_addr,
|
||||
unsigned int *irq)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -238,8 +256,9 @@ static int pci_card_data(struct pcilst_struct *inova,
|
||||
/****************************************************************************/
|
||||
/* select and alloc card */
|
||||
static struct pcilst_struct *select_and_alloc_pci_card(unsigned short vendor_id,
|
||||
unsigned short device_id, unsigned short pci_bus,
|
||||
unsigned short pci_slot)
|
||||
unsigned short device_id,
|
||||
unsigned short pci_bus,
|
||||
unsigned short pci_slot)
|
||||
{
|
||||
struct pcilst_struct *card;
|
||||
int err;
|
||||
@@ -253,16 +272,17 @@ static struct pcilst_struct *select_and_alloc_pci_card(unsigned short vendor_id,
|
||||
}
|
||||
} else {
|
||||
switch (find_free_pci_card_by_position(vendor_id, device_id,
|
||||
pci_bus, pci_slot, &card)) {
|
||||
pci_bus, pci_slot,
|
||||
&card)) {
|
||||
case 1:
|
||||
printk
|
||||
(" - Card not found on requested position b:s %d:%d!\n",
|
||||
pci_bus, pci_slot);
|
||||
(" - Card not found on requested position b:s %d:%d!\n",
|
||||
pci_bus, pci_slot);
|
||||
return NULL;
|
||||
case 2:
|
||||
printk
|
||||
(" - Card on requested position is used b:s %d:%d!\n",
|
||||
pci_bus, pci_slot);
|
||||
(" - Card on requested position is used b:s %d:%d!\n",
|
||||
pci_bus, pci_slot);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,11 +154,11 @@ struct pci20xxx_private {
|
||||
union pci20xxx_subdev_private subdev_private[PCI20000_MODULES];
|
||||
};
|
||||
|
||||
|
||||
#define devpriv ((struct pci20xxx_private *)dev->private)
|
||||
#define CHAN (CR_CHAN(it->chanlist[0]))
|
||||
|
||||
static int pci20xxx_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int pci20xxx_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int pci20xxx_detach(struct comedi_device *dev);
|
||||
|
||||
static struct comedi_driver driver_pci20xxx = {
|
||||
@@ -169,10 +169,11 @@ static struct comedi_driver driver_pci20xxx = {
|
||||
};
|
||||
|
||||
static int pci20006_init(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
int opt0, int opt1);
|
||||
int opt0, int opt1);
|
||||
static int pci20341_init(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
int opt0, int opt1);
|
||||
static int pci20xxx_dio_init(struct comedi_device *dev, struct comedi_subdevice *s);
|
||||
int opt0, int opt1);
|
||||
static int pci20xxx_dio_init(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s);
|
||||
|
||||
/*
|
||||
options[0] Board base address
|
||||
@@ -201,7 +202,8 @@ static int pci20xxx_dio_init(struct comedi_device *dev, struct comedi_subdevice
|
||||
1 == unipolar 10V (0V -- +10V)
|
||||
2 == bipolar 5V (-5V -- +5V)
|
||||
*/
|
||||
static int pci20xxx_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
static int pci20xxx_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it)
|
||||
{
|
||||
unsigned char i;
|
||||
int ret;
|
||||
@@ -223,7 +225,9 @@ static int pci20xxx_attach(struct comedi_device *dev, struct comedi_devconfig *i
|
||||
/* Check PCI-20001 C-2A Carrier Board ID */
|
||||
if ((readb(devpriv->ioaddr) & PCI20000_ID) != PCI20000_ID) {
|
||||
printk("comedi%d: ii_pci20kc", dev->minor);
|
||||
printk(" PCI-20001 C-2A Carrier Board at base=0x%p not found !\n", devpriv->ioaddr);
|
||||
printk
|
||||
(" PCI-20001 C-2A Carrier Board at base=0x%p not found !\n",
|
||||
devpriv->ioaddr);
|
||||
return -EINVAL;
|
||||
}
|
||||
printk("comedi%d:\n", dev->minor);
|
||||
@@ -237,22 +241,24 @@ static int pci20xxx_attach(struct comedi_device *dev, struct comedi_devconfig *i
|
||||
switch (id) {
|
||||
case PCI20006_ID:
|
||||
sdp->pci20006.iobase =
|
||||
devpriv->ioaddr + (i + 1) * PCI20000_OFFSET;
|
||||
devpriv->ioaddr + (i + 1) * PCI20000_OFFSET;
|
||||
pci20006_init(dev, s, it->options[2 * i + 2],
|
||||
it->options[2 * i + 3]);
|
||||
it->options[2 * i + 3]);
|
||||
printk("comedi%d: ii_pci20kc", dev->minor);
|
||||
printk(" PCI-20006 module in slot %d \n", i + 1);
|
||||
break;
|
||||
case PCI20341_ID:
|
||||
sdp->pci20341.iobase =
|
||||
devpriv->ioaddr + (i + 1) * PCI20000_OFFSET;
|
||||
devpriv->ioaddr + (i + 1) * PCI20000_OFFSET;
|
||||
pci20341_init(dev, s, it->options[2 * i + 2],
|
||||
it->options[2 * i + 3]);
|
||||
it->options[2 * i + 3]);
|
||||
printk("comedi%d: ii_pci20kc", dev->minor);
|
||||
printk(" PCI-20341 module in slot %d \n", i + 1);
|
||||
break;
|
||||
default:
|
||||
printk("ii_pci20kc: unknown module code 0x%02x in slot %d: module disabled\n", id, i);
|
||||
printk
|
||||
("ii_pci20kc: unknown module code 0x%02x in slot %d: module disabled\n",
|
||||
id, i);
|
||||
/* fall through */
|
||||
case PCI20xxx_EMPTY_ID:
|
||||
s->type = COMEDI_SUBD_UNUSED;
|
||||
@@ -275,10 +281,12 @@ static int pci20xxx_detach(struct comedi_device *dev)
|
||||
|
||||
/* pci20006m */
|
||||
|
||||
static int pci20006_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int pci20006_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int pci20006_insn_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int pci20006_insn_write(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
static const struct comedi_lrange *pci20006_range_list[] = {
|
||||
&range_bipolar10,
|
||||
@@ -287,7 +295,7 @@ static const struct comedi_lrange *pci20006_range_list[] = {
|
||||
};
|
||||
|
||||
static int pci20006_init(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
int opt0, int opt1)
|
||||
int opt0, int opt1)
|
||||
{
|
||||
union pci20xxx_subdev_private *sdp = s->private;
|
||||
|
||||
@@ -311,8 +319,9 @@ static int pci20006_init(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pci20006_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int pci20006_insn_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
union pci20xxx_subdev_private *sdp = s->private;
|
||||
|
||||
@@ -321,8 +330,9 @@ static int pci20006_insn_read(struct comedi_device *dev, struct comedi_subdevice
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pci20006_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int pci20006_insn_write(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
union pci20xxx_subdev_private *sdp = s->private;
|
||||
int hi, lo;
|
||||
@@ -354,15 +364,17 @@ static int pci20006_insn_write(struct comedi_device *dev, struct comedi_subdevic
|
||||
|
||||
/* PCI20341M */
|
||||
|
||||
static int pci20341_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int pci20341_insn_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
static const int pci20341_timebase[] = { 0x00, 0x00, 0x00, 0x04 };
|
||||
static const int pci20341_settling_time[] = { 0x58, 0x58, 0x93, 0x99 };
|
||||
|
||||
static const struct comedi_lrange range_bipolar0_5 = { 1, {BIP_RANGE(0.5)} };
|
||||
static const struct comedi_lrange range_bipolar0_05 = { 1, {BIP_RANGE(0.05)} };
|
||||
static const struct comedi_lrange range_bipolar0_025 = { 1, {BIP_RANGE(0.025)} };
|
||||
static const struct comedi_lrange range_bipolar0_025 =
|
||||
{ 1, {BIP_RANGE(0.025)} };
|
||||
|
||||
static const struct comedi_lrange *const pci20341_ranges[] = {
|
||||
&range_bipolar5,
|
||||
@@ -372,7 +384,7 @@ static const struct comedi_lrange *const pci20341_ranges[] = {
|
||||
};
|
||||
|
||||
static int pci20341_init(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
int opt0, int opt1)
|
||||
int opt0, int opt1)
|
||||
{
|
||||
union pci20xxx_subdev_private *sdp = s->private;
|
||||
int option;
|
||||
@@ -402,10 +414,11 @@ static int pci20341_init(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pci20341_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int pci20341_insn_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
union pci20xxx_subdev_private *sdp = s->private;
|
||||
union pci20xxx_subdev_private *sdp = s->private;
|
||||
unsigned int i = 0, j = 0;
|
||||
int lo, hi;
|
||||
unsigned char eoc; /* end of conversion */
|
||||
@@ -414,7 +427,7 @@ static int pci20341_insn_read(struct comedi_device *dev, struct comedi_subdevice
|
||||
|
||||
writeb(1, sdp->iobase + PCI20341_LCHAN_ADDR_REG); /* write number of input channels */
|
||||
clb = PCI20341_DAISY_CHAIN | PCI20341_MUX | (sdp->pci20341.ai_gain << 3)
|
||||
| CR_CHAN(insn->chanspec);
|
||||
| CR_CHAN(insn->chanspec);
|
||||
writeb(clb, sdp->iobase + PCI20341_CHAN_LIST);
|
||||
writeb(0x00, sdp->iobase + PCI20341_CC_RESET); /* reset settling time counter and trigger delay counter */
|
||||
writeb(0x00, sdp->iobase + PCI20341_CHAN_RESET);
|
||||
@@ -434,13 +447,15 @@ static int pci20341_insn_read(struct comedi_device *dev, struct comedi_subdevice
|
||||
eoc = readb(sdp->iobase + PCI20341_STATUS_REG);
|
||||
}
|
||||
if (j >= 100) {
|
||||
printk("comedi%d: pci20xxx: AI interrupt channel %i polling exit !\n", dev->minor, i);
|
||||
printk
|
||||
("comedi%d: pci20xxx: AI interrupt channel %i polling exit !\n",
|
||||
dev->minor, i);
|
||||
return -EINVAL;
|
||||
}
|
||||
lo = readb(sdp->iobase + PCI20341_LDATA);
|
||||
hi = readb(sdp->iobase + PCI20341_LDATA + 1);
|
||||
boarddata = lo + 0x100 * hi;
|
||||
data[i] = (short) ((boarddata + 0x8000) & 0xffff); /* board-data -> comedi-data */
|
||||
data[i] = (short)((boarddata + 0x8000) & 0xffff); /* board-data -> comedi-data */
|
||||
}
|
||||
|
||||
return i;
|
||||
@@ -448,14 +463,19 @@ static int pci20341_insn_read(struct comedi_device *dev, struct comedi_subdevice
|
||||
|
||||
/* native DIO */
|
||||
|
||||
static void pci20xxx_dio_config(struct comedi_device *dev, struct comedi_subdevice *s);
|
||||
static int pci20xxx_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int pci20xxx_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static void pci20xxx_dio_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s);
|
||||
static int pci20xxx_dio_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int pci20xxx_dio_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
|
||||
/* initialize struct pci20xxx_private */
|
||||
static int pci20xxx_dio_init(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
static int pci20xxx_dio_init(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
|
||||
s->type = COMEDI_SUBD_DIO;
|
||||
@@ -474,8 +494,10 @@ static int pci20xxx_dio_init(struct comedi_device *dev, struct comedi_subdevice
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pci20xxx_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int pci20xxx_dio_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
int mask, bits;
|
||||
|
||||
@@ -499,8 +521,9 @@ static int pci20xxx_dio_insn_config(struct comedi_device *dev, struct comedi_sub
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int pci20xxx_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int pci20xxx_dio_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
unsigned int mask = data[0];
|
||||
|
||||
@@ -510,16 +533,16 @@ static int pci20xxx_dio_insn_bits(struct comedi_device *dev, struct comedi_subde
|
||||
mask &= s->io_bits;
|
||||
if (mask & 0x000000ff)
|
||||
writeb((s->state >> 0) & 0xff,
|
||||
devpriv->ioaddr + PCI20000_DIO_0);
|
||||
devpriv->ioaddr + PCI20000_DIO_0);
|
||||
if (mask & 0x0000ff00)
|
||||
writeb((s->state >> 8) & 0xff,
|
||||
devpriv->ioaddr + PCI20000_DIO_1);
|
||||
devpriv->ioaddr + PCI20000_DIO_1);
|
||||
if (mask & 0x00ff0000)
|
||||
writeb((s->state >> 16) & 0xff,
|
||||
devpriv->ioaddr + PCI20000_DIO_2);
|
||||
devpriv->ioaddr + PCI20000_DIO_2);
|
||||
if (mask & 0xff000000)
|
||||
writeb((s->state >> 24) & 0xff,
|
||||
devpriv->ioaddr + PCI20000_DIO_3);
|
||||
devpriv->ioaddr + PCI20000_DIO_3);
|
||||
|
||||
data[1] = readb(devpriv->ioaddr + PCI20000_DIO_0);
|
||||
data[1] |= readb(devpriv->ioaddr + PCI20000_DIO_1) << 8;
|
||||
@@ -529,7 +552,8 @@ static int pci20xxx_dio_insn_bits(struct comedi_device *dev, struct comedi_subde
|
||||
return 2;
|
||||
}
|
||||
|
||||
static void pci20xxx_dio_config(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
static void pci20xxx_dio_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
unsigned char control_01;
|
||||
unsigned char control_23;
|
||||
@@ -543,7 +567,7 @@ static void pci20xxx_dio_config(struct comedi_device *dev, struct comedi_subdevi
|
||||
/* output port 0 */
|
||||
control_01 &= PCI20000_DIO_EOC;
|
||||
buffer = (buffer & (~(DIO_BE << DIO_PS_0))) | (DIO_BO <<
|
||||
DIO_PS_0);
|
||||
DIO_PS_0);
|
||||
} else {
|
||||
/* input port 0 */
|
||||
control_01 = (control_01 & DIO_CAND) | PCI20000_DIO_EIC;
|
||||
@@ -553,7 +577,7 @@ static void pci20xxx_dio_config(struct comedi_device *dev, struct comedi_subdevi
|
||||
/* output port 1 */
|
||||
control_01 &= PCI20000_DIO_OOC;
|
||||
buffer = (buffer & (~(DIO_BE << DIO_PS_1))) | (DIO_BO <<
|
||||
DIO_PS_1);
|
||||
DIO_PS_1);
|
||||
} else {
|
||||
/* input port 1 */
|
||||
control_01 = (control_01 & DIO_CAND) | PCI20000_DIO_OIC;
|
||||
@@ -563,7 +587,7 @@ static void pci20xxx_dio_config(struct comedi_device *dev, struct comedi_subdevi
|
||||
/* output port 2 */
|
||||
control_23 &= PCI20000_DIO_EOC;
|
||||
buffer = (buffer & (~(DIO_BE << DIO_PS_2))) | (DIO_BO <<
|
||||
DIO_PS_2);
|
||||
DIO_PS_2);
|
||||
} else {
|
||||
/* input port 2 */
|
||||
control_23 = (control_23 & DIO_CAND) | PCI20000_DIO_EIC;
|
||||
@@ -573,7 +597,7 @@ static void pci20xxx_dio_config(struct comedi_device *dev, struct comedi_subdevi
|
||||
/* output port 3 */
|
||||
control_23 &= PCI20000_DIO_OOC;
|
||||
buffer = (buffer & (~(DIO_BE << DIO_PS_3))) | (DIO_BO <<
|
||||
DIO_PS_3);
|
||||
DIO_PS_3);
|
||||
} else {
|
||||
/* input port 3 */
|
||||
control_23 = (control_23 & DIO_CAND) | PCI20000_DIO_OIC;
|
||||
@@ -598,7 +622,8 @@ static void pci20xxx_do(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
writeb((s->state >> 24) & 0xff, devpriv->ioaddr + PCI20000_DIO_3);
|
||||
}
|
||||
|
||||
static unsigned int pci20xxx_di(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
static unsigned int pci20xxx_di(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
/* XXX same note as above */
|
||||
unsigned int bits;
|
||||
|
||||
@@ -56,7 +56,8 @@ Devices: [JR3] PCI force sensor board (jr3_pci)
|
||||
#define PCI_DEVICE_ID_JR3_3_CHANNEL 0x3113
|
||||
#define PCI_DEVICE_ID_JR3_4_CHANNEL 0x3114
|
||||
|
||||
static int jr3_pci_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int jr3_pci_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int jr3_pci_detach(struct comedi_device *dev);
|
||||
|
||||
static struct comedi_driver driver_jr3_pci = {
|
||||
@@ -67,15 +68,16 @@ static struct comedi_driver driver_jr3_pci = {
|
||||
};
|
||||
|
||||
static DEFINE_PCI_DEVICE_TABLE(jr3_pci_pci_table) = {
|
||||
{PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_1_CHANNEL,
|
||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_2_CHANNEL,
|
||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_3_CHANNEL,
|
||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_4_CHANNEL,
|
||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{0}
|
||||
{
|
||||
PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_1_CHANNEL,
|
||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_2_CHANNEL,
|
||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_3_CHANNEL,
|
||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_4_CHANNEL,
|
||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
0}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, jr3_pci_pci_table);
|
||||
@@ -89,14 +91,12 @@ struct jr3_pci_dev_private {
|
||||
struct timer_list timer;
|
||||
};
|
||||
|
||||
|
||||
struct poll_delay_t {
|
||||
|
||||
int min;
|
||||
int max;
|
||||
};
|
||||
|
||||
|
||||
struct jr3_pci_subdev_private {
|
||||
volatile struct jr3_channel *channel;
|
||||
unsigned long next_time_min;
|
||||
@@ -124,7 +124,7 @@ struct jr3_pci_subdev_private {
|
||||
/* Hotplug firmware loading stuff */
|
||||
|
||||
typedef int comedi_firmware_callback(struct comedi_device *dev,
|
||||
const u8 *data, size_t size);
|
||||
const u8 * data, size_t size);
|
||||
|
||||
static int comedi_load_firmware(struct comedi_device *dev, char *name,
|
||||
comedi_firmware_callback cb)
|
||||
@@ -143,7 +143,7 @@ static int comedi_load_firmware(struct comedi_device *dev, char *name,
|
||||
strcat(firmware_path, prefix);
|
||||
strcat(firmware_path, name);
|
||||
result = request_firmware(&fw, firmware_path,
|
||||
&devpriv->pci_dev->dev);
|
||||
&devpriv->pci_dev->dev);
|
||||
if (result == 0) {
|
||||
if (!cb)
|
||||
result = -EINVAL;
|
||||
@@ -178,7 +178,7 @@ struct transform_t {
|
||||
};
|
||||
|
||||
static void set_transforms(volatile struct jr3_channel *channel,
|
||||
struct transform_t transf, short num)
|
||||
struct transform_t transf, short num)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -197,7 +197,8 @@ static void set_transforms(volatile struct jr3_channel *channel,
|
||||
}
|
||||
}
|
||||
|
||||
static void use_transform(volatile struct jr3_channel *channel, short transf_num)
|
||||
static void use_transform(volatile struct jr3_channel *channel,
|
||||
short transf_num)
|
||||
{
|
||||
set_s16(&channel->command_word0, 0x0500 + (transf_num & 0x000f));
|
||||
}
|
||||
@@ -222,12 +223,12 @@ struct six_axis_t {
|
||||
};
|
||||
|
||||
static void set_full_scales(volatile struct jr3_channel *channel,
|
||||
struct six_axis_t full_scale)
|
||||
struct six_axis_t full_scale)
|
||||
{
|
||||
printk("%d %d %d %d %d %d\n",
|
||||
full_scale.fx,
|
||||
full_scale.fy,
|
||||
full_scale.fz, full_scale.mx, full_scale.my, full_scale.mz);
|
||||
full_scale.fx,
|
||||
full_scale.fy,
|
||||
full_scale.fz, full_scale.mx, full_scale.my, full_scale.mz);
|
||||
set_s16(&channel->full_scale.fx, full_scale.fx);
|
||||
set_s16(&channel->full_scale.fy, full_scale.fy);
|
||||
set_s16(&channel->full_scale.fz, full_scale.fz);
|
||||
@@ -237,7 +238,8 @@ static void set_full_scales(volatile struct jr3_channel *channel,
|
||||
set_s16(&channel->command_word0, 0x0a00);
|
||||
}
|
||||
|
||||
static struct six_axis_t get_min_full_scales(volatile struct jr3_channel *channel)
|
||||
static struct six_axis_t get_min_full_scales(volatile struct jr3_channel
|
||||
*channel)
|
||||
{
|
||||
struct six_axis_t result;
|
||||
result.fx = get_s16(&channel->min_full_scale.fx);
|
||||
@@ -249,7 +251,8 @@ static struct six_axis_t get_min_full_scales(volatile struct jr3_channel *channe
|
||||
return result;
|
||||
}
|
||||
|
||||
static struct six_axis_t get_max_full_scales(volatile struct jr3_channel *channel)
|
||||
static struct six_axis_t get_max_full_scales(volatile struct jr3_channel
|
||||
*channel)
|
||||
{
|
||||
struct six_axis_t result;
|
||||
result.fx = get_s16(&channel->max_full_scale.fx);
|
||||
@@ -261,8 +264,9 @@ static struct six_axis_t get_max_full_scales(volatile struct jr3_channel *channe
|
||||
return result;
|
||||
}
|
||||
|
||||
static int jr3_pci_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int jr3_pci_ai_insn_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int result;
|
||||
struct jr3_pci_subdev_private *p;
|
||||
@@ -277,9 +281,8 @@ static int jr3_pci_ai_insn_read(struct comedi_device *dev, struct comedi_subdevi
|
||||
|
||||
result = insn->n;
|
||||
if (p->state != state_jr3_done ||
|
||||
(get_u16(&p->channel->
|
||||
errors) & (watch_dog | watch_dog2 |
|
||||
sensor_change))) {
|
||||
(get_u16(&p->channel->errors) & (watch_dog | watch_dog2 |
|
||||
sensor_change))) {
|
||||
/* No sensor or sensor changed */
|
||||
if (p->state == state_jr3_done) {
|
||||
/* Restart polling */
|
||||
@@ -299,59 +302,51 @@ static int jr3_pci_ai_insn_read(struct comedi_device *dev, struct comedi_subdevi
|
||||
int F = 0;
|
||||
switch (axis) {
|
||||
case 0:{
|
||||
F = get_s16(&p->
|
||||
channel->
|
||||
filter[filter].
|
||||
fx);
|
||||
F = get_s16
|
||||
(&p->channel->filter
|
||||
[filter].fx);
|
||||
}
|
||||
break;
|
||||
case 1:{
|
||||
F = get_s16(&p->
|
||||
channel->
|
||||
filter[filter].
|
||||
fy);
|
||||
F = get_s16
|
||||
(&p->channel->filter
|
||||
[filter].fy);
|
||||
}
|
||||
break;
|
||||
case 2:{
|
||||
F = get_s16(&p->
|
||||
channel->
|
||||
filter[filter].
|
||||
fz);
|
||||
F = get_s16
|
||||
(&p->channel->filter
|
||||
[filter].fz);
|
||||
}
|
||||
break;
|
||||
case 3:{
|
||||
F = get_s16(&p->
|
||||
channel->
|
||||
filter[filter].
|
||||
mx);
|
||||
F = get_s16
|
||||
(&p->channel->filter
|
||||
[filter].mx);
|
||||
}
|
||||
break;
|
||||
case 4:{
|
||||
F = get_s16(&p->
|
||||
channel->
|
||||
filter[filter].
|
||||
my);
|
||||
F = get_s16
|
||||
(&p->channel->filter
|
||||
[filter].my);
|
||||
}
|
||||
break;
|
||||
case 5:{
|
||||
F = get_s16(&p->
|
||||
channel->
|
||||
filter[filter].
|
||||
mz);
|
||||
F = get_s16
|
||||
(&p->channel->filter
|
||||
[filter].mz);
|
||||
}
|
||||
break;
|
||||
case 6:{
|
||||
F = get_s16(&p->
|
||||
channel->
|
||||
filter[filter].
|
||||
v1);
|
||||
F = get_s16
|
||||
(&p->channel->filter
|
||||
[filter].v1);
|
||||
}
|
||||
break;
|
||||
case 7:{
|
||||
F = get_s16(&p->
|
||||
channel->
|
||||
filter[filter].
|
||||
v2);
|
||||
F = get_s16
|
||||
(&p->channel->filter
|
||||
[filter].v2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -362,14 +357,14 @@ static int jr3_pci_ai_insn_read(struct comedi_device *dev, struct comedi_subdevi
|
||||
data[i] = 0;
|
||||
} else {
|
||||
data[i] =
|
||||
get_u16(&p->channel->model_no);
|
||||
get_u16(&p->channel->model_no);
|
||||
}
|
||||
} else if (channel == 57) {
|
||||
if (p->state != state_jr3_done) {
|
||||
data[i] = 0;
|
||||
} else {
|
||||
data[i] =
|
||||
get_u16(&p->channel->serial_no);
|
||||
get_u16(&p->channel->serial_no);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -389,12 +384,12 @@ static void jr3_pci_open(struct comedi_device *dev)
|
||||
p = dev->subdevices[i].private;
|
||||
if (p) {
|
||||
printk("serial: %p %d (%d)\n", p, p->serial_no,
|
||||
p->channel_no);
|
||||
p->channel_no);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int read_idm_word(const u8 *data, size_t size, int *pos, unsigned int *val)
|
||||
int read_idm_word(const u8 * data, size_t size, int *pos, unsigned int *val)
|
||||
{
|
||||
int result = 0;
|
||||
if (pos != 0 && val != 0) {
|
||||
@@ -416,8 +411,8 @@ int read_idm_word(const u8 *data, size_t size, int *pos, unsigned int *val)
|
||||
return result;
|
||||
}
|
||||
|
||||
static int jr3_download_firmware(struct comedi_device *dev, const u8 *data,
|
||||
size_t size)
|
||||
static int jr3_download_firmware(struct comedi_device *dev, const u8 * data,
|
||||
size_t size)
|
||||
{
|
||||
/*
|
||||
* IDM file format is:
|
||||
@@ -461,24 +456,23 @@ static int jr3_download_firmware(struct comedi_device *dev, const u8 *data,
|
||||
while (more) {
|
||||
unsigned int count, addr;
|
||||
more = more
|
||||
&& read_idm_word(data, size, &pos,
|
||||
&count);
|
||||
&& read_idm_word(data, size, &pos, &count);
|
||||
if (more && count == 0xffff) {
|
||||
break;
|
||||
}
|
||||
more = more
|
||||
&& read_idm_word(data, size, &pos,
|
||||
&addr);
|
||||
&& read_idm_word(data, size, &pos, &addr);
|
||||
printk("Loading#%d %4.4x bytes at %4.4x\n", i,
|
||||
count, addr);
|
||||
count, addr);
|
||||
while (more && count > 0) {
|
||||
if (addr & 0x4000) {
|
||||
/* 16 bit data, never seen in real life!! */
|
||||
unsigned int data1;
|
||||
|
||||
more = more
|
||||
&& read_idm_word(data,
|
||||
size, &pos, &data1);
|
||||
&& read_idm_word(data,
|
||||
size, &pos,
|
||||
&data1);
|
||||
count--;
|
||||
/* printk("jr3_data, not tested\n"); */
|
||||
/* jr3[addr + 0x20000 * pnum] = data1; */
|
||||
@@ -487,21 +481,23 @@ static int jr3_download_firmware(struct comedi_device *dev, const u8 *data,
|
||||
unsigned int data1, data2;
|
||||
|
||||
more = more
|
||||
&& read_idm_word(data,
|
||||
size, &pos, &data1);
|
||||
&& read_idm_word(data,
|
||||
size, &pos,
|
||||
&data1);
|
||||
more = more
|
||||
&& read_idm_word(data,
|
||||
size, &pos, &data2);
|
||||
&& read_idm_word(data, size,
|
||||
&pos,
|
||||
&data2);
|
||||
count -= 2;
|
||||
if (more) {
|
||||
set_u16(&p->iobase->
|
||||
channel[i].
|
||||
program_low
|
||||
set_u16(&p->
|
||||
iobase->channel
|
||||
[i].program_low
|
||||
[addr], data1);
|
||||
udelay(1);
|
||||
set_u16(&p->iobase->
|
||||
channel[i].
|
||||
program_high
|
||||
set_u16(&p->
|
||||
iobase->channel
|
||||
[i].program_high
|
||||
[addr], data2);
|
||||
udelay(1);
|
||||
|
||||
@@ -538,7 +534,7 @@ static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice *s)
|
||||
u16 model_no = get_u16(&channel->model_no);
|
||||
u16 serial_no = get_u16(&channel->serial_no);
|
||||
if ((errors & (watch_dog | watch_dog2)) ||
|
||||
model_no == 0 || serial_no == 0) {
|
||||
model_no == 0 || serial_no == 0) {
|
||||
/*
|
||||
* Still no sensor, keep on polling. Since it takes up to 10 seconds
|
||||
* for offsets to stabilize, polling each second should suffice.
|
||||
@@ -547,7 +543,7 @@ static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice *s)
|
||||
} else {
|
||||
p->retries = 0;
|
||||
p->state =
|
||||
state_jr3_init_wait_for_offset;
|
||||
state_jr3_init_wait_for_offset;
|
||||
result = poll_delay_min_max(1000, 2000);
|
||||
}
|
||||
}
|
||||
@@ -561,40 +557,44 @@ static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice *s)
|
||||
struct transform_t transf;
|
||||
|
||||
p->model_no =
|
||||
get_u16(&channel->model_no);
|
||||
get_u16(&channel->model_no);
|
||||
p->serial_no =
|
||||
get_u16(&channel->serial_no);
|
||||
get_u16(&channel->serial_no);
|
||||
|
||||
printk("Setting transform for channel %d\n", p->channel_no);
|
||||
printk
|
||||
("Setting transform for channel %d\n",
|
||||
p->channel_no);
|
||||
printk("Sensor Model = %i\n",
|
||||
p->model_no);
|
||||
p->model_no);
|
||||
printk("Sensor Serial = %i\n",
|
||||
p->serial_no);
|
||||
p->serial_no);
|
||||
|
||||
/* Transformation all zeros */
|
||||
transf.link[0].link_type =
|
||||
(enum link_types)0;
|
||||
(enum link_types)0;
|
||||
transf.link[0].link_amount = 0;
|
||||
transf.link[1].link_type =
|
||||
(enum link_types)0;
|
||||
(enum link_types)0;
|
||||
transf.link[1].link_amount = 0;
|
||||
transf.link[2].link_type =
|
||||
(enum link_types)0;
|
||||
(enum link_types)0;
|
||||
transf.link[2].link_amount = 0;
|
||||
transf.link[3].link_type =
|
||||
(enum link_types)0;
|
||||
(enum link_types)0;
|
||||
transf.link[3].link_amount = 0;
|
||||
|
||||
set_transforms(channel, transf, 0);
|
||||
use_transform(channel, 0);
|
||||
p->state =
|
||||
state_jr3_init_transform_complete;
|
||||
state_jr3_init_transform_complete;
|
||||
result = poll_delay_min_max(20, 100); /* Allow 20 ms for completion */
|
||||
}
|
||||
} break;
|
||||
case state_jr3_init_transform_complete:{
|
||||
if (!is_complete(channel)) {
|
||||
printk("state_jr3_init_transform_complete complete = %d\n", is_complete(channel));
|
||||
printk
|
||||
("state_jr3_init_transform_complete complete = %d\n",
|
||||
is_complete(channel));
|
||||
result = poll_delay_min_max(20, 100);
|
||||
} else {
|
||||
/* Set full scale */
|
||||
@@ -602,7 +602,7 @@ static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice *s)
|
||||
struct six_axis_t max_full_scale;
|
||||
|
||||
min_full_scale =
|
||||
get_min_full_scales(channel);
|
||||
get_min_full_scales(channel);
|
||||
printk("Obtained Min. Full Scales:\n");
|
||||
printk("%i ", (min_full_scale).fx);
|
||||
printk("%i ", (min_full_scale).fy);
|
||||
@@ -613,7 +613,7 @@ static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice *s)
|
||||
printk("\n");
|
||||
|
||||
max_full_scale =
|
||||
get_max_full_scales(channel);
|
||||
get_max_full_scales(channel);
|
||||
printk("Obtained Max. Full Scales:\n");
|
||||
printk("%i ", (max_full_scale).fx);
|
||||
printk("%i ", (max_full_scale).fy);
|
||||
@@ -624,17 +624,19 @@ static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice *s)
|
||||
printk("\n");
|
||||
|
||||
set_full_scales(channel,
|
||||
max_full_scale);
|
||||
max_full_scale);
|
||||
|
||||
p->state =
|
||||
state_jr3_init_set_full_scale_complete;
|
||||
state_jr3_init_set_full_scale_complete;
|
||||
result = poll_delay_min_max(20, 100); /* Allow 20 ms for completion */
|
||||
}
|
||||
}
|
||||
break;
|
||||
case state_jr3_init_set_full_scale_complete:{
|
||||
if (!is_complete(channel)) {
|
||||
printk("state_jr3_init_set_full_scale_complete complete = %d\n", is_complete(channel));
|
||||
printk
|
||||
("state_jr3_init_set_full_scale_complete complete = %d\n",
|
||||
is_complete(channel));
|
||||
result = poll_delay_min_max(20, 100);
|
||||
} else {
|
||||
volatile struct force_array *full_scale;
|
||||
@@ -642,32 +644,29 @@ static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice *s)
|
||||
/* Use ranges in kN or we will overflow arount 2000N! */
|
||||
full_scale = &channel->full_scale;
|
||||
p->range[0].range.min =
|
||||
-get_s16(&full_scale->fx) *
|
||||
1000;
|
||||
-get_s16(&full_scale->fx) * 1000;
|
||||
p->range[0].range.max =
|
||||
get_s16(&full_scale->fx) * 1000;
|
||||
get_s16(&full_scale->fx) * 1000;
|
||||
p->range[1].range.min =
|
||||
-get_s16(&full_scale->fy) *
|
||||
1000;
|
||||
-get_s16(&full_scale->fy) * 1000;
|
||||
p->range[1].range.max =
|
||||
get_s16(&full_scale->fy) * 1000;
|
||||
get_s16(&full_scale->fy) * 1000;
|
||||
p->range[2].range.min =
|
||||
-get_s16(&full_scale->fz) *
|
||||
1000;
|
||||
-get_s16(&full_scale->fz) * 1000;
|
||||
p->range[2].range.max =
|
||||
get_s16(&full_scale->fz) * 1000;
|
||||
get_s16(&full_scale->fz) * 1000;
|
||||
p->range[3].range.min =
|
||||
-get_s16(&full_scale->mx) * 100;
|
||||
-get_s16(&full_scale->mx) * 100;
|
||||
p->range[3].range.max =
|
||||
get_s16(&full_scale->mx) * 100;
|
||||
get_s16(&full_scale->mx) * 100;
|
||||
p->range[4].range.min =
|
||||
-get_s16(&full_scale->my) * 100;
|
||||
-get_s16(&full_scale->my) * 100;
|
||||
p->range[4].range.max =
|
||||
get_s16(&full_scale->my) * 100;
|
||||
get_s16(&full_scale->my) * 100;
|
||||
p->range[5].range.min =
|
||||
-get_s16(&full_scale->mz) * 100;
|
||||
-get_s16(&full_scale->mz) * 100;
|
||||
p->range[5].range.max =
|
||||
get_s16(&full_scale->mz) * 100;
|
||||
get_s16(&full_scale->mz) * 100;
|
||||
p->range[6].range.min = -get_s16(&full_scale->v1) * 100; /* ?? */
|
||||
p->range[6].range.max = get_s16(&full_scale->v1) * 100; /* ?? */
|
||||
p->range[7].range.min = -get_s16(&full_scale->v2) * 100; /* ?? */
|
||||
@@ -679,27 +678,38 @@ static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice *s)
|
||||
int i;
|
||||
for (i = 0; i < 9; i++) {
|
||||
printk("%d %d - %d\n",
|
||||
i,
|
||||
p->range[i].
|
||||
range.min,
|
||||
p->range[i].
|
||||
range.max);
|
||||
i,
|
||||
p->
|
||||
range[i].range.
|
||||
min,
|
||||
p->
|
||||
range[i].range.
|
||||
max);
|
||||
}
|
||||
}
|
||||
|
||||
use_offset(channel, 0);
|
||||
p->state =
|
||||
state_jr3_init_use_offset_complete;
|
||||
state_jr3_init_use_offset_complete;
|
||||
result = poll_delay_min_max(40, 100); /* Allow 40 ms for completion */
|
||||
}
|
||||
}
|
||||
break;
|
||||
case state_jr3_init_use_offset_complete:{
|
||||
if (!is_complete(channel)) {
|
||||
printk("state_jr3_init_use_offset_complete complete = %d\n", is_complete(channel));
|
||||
printk
|
||||
("state_jr3_init_use_offset_complete complete = %d\n",
|
||||
is_complete(channel));
|
||||
result = poll_delay_min_max(20, 100);
|
||||
} else {
|
||||
printk("Default offsets %d %d %d %d %d %d\n", get_s16(&channel->offsets.fx), get_s16(&channel->offsets.fy), get_s16(&channel->offsets.fz), get_s16(&channel->offsets.mx), get_s16(&channel->offsets.my), get_s16(&channel->offsets.mz));
|
||||
printk
|
||||
("Default offsets %d %d %d %d %d %d\n",
|
||||
get_s16(&channel->offsets.fx),
|
||||
get_s16(&channel->offsets.fy),
|
||||
get_s16(&channel->offsets.fz),
|
||||
get_s16(&channel->offsets.mx),
|
||||
get_s16(&channel->offsets.my),
|
||||
get_s16(&channel->offsets.mz));
|
||||
|
||||
set_s16(&channel->offsets.fx, 0);
|
||||
set_s16(&channel->offsets.fy, 0);
|
||||
@@ -730,7 +740,7 @@ static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice *s)
|
||||
static void jr3_pci_poll_dev(unsigned long data)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct comedi_device *dev = (struct comedi_device *) data;
|
||||
struct comedi_device *dev = (struct comedi_device *)data;
|
||||
struct jr3_pci_dev_private *devpriv = dev->private;
|
||||
unsigned long now;
|
||||
int delay;
|
||||
@@ -741,15 +751,16 @@ static void jr3_pci_poll_dev(unsigned long data)
|
||||
now = jiffies;
|
||||
/* Poll all channels that are ready to be polled */
|
||||
for (i = 0; i < devpriv->n_channels; i++) {
|
||||
struct jr3_pci_subdev_private *subdevpriv = dev->subdevices[i].private;
|
||||
struct jr3_pci_subdev_private *subdevpriv =
|
||||
dev->subdevices[i].private;
|
||||
if (now > subdevpriv->next_time_min) {
|
||||
struct poll_delay_t sub_delay;
|
||||
|
||||
sub_delay = jr3_pci_poll_subdevice(&dev->subdevices[i]);
|
||||
subdevpriv->next_time_min =
|
||||
jiffies + msecs_to_jiffies(sub_delay.min);
|
||||
jiffies + msecs_to_jiffies(sub_delay.min);
|
||||
subdevpriv->next_time_max =
|
||||
jiffies + msecs_to_jiffies(sub_delay.max);
|
||||
jiffies + msecs_to_jiffies(sub_delay.max);
|
||||
if (sub_delay.max && sub_delay.max < delay) {
|
||||
/*
|
||||
* Wake up as late as possible -> poll as many channels as possible
|
||||
@@ -765,7 +776,8 @@ static void jr3_pci_poll_dev(unsigned long data)
|
||||
add_timer(&devpriv->timer);
|
||||
}
|
||||
|
||||
static int jr3_pci_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
static int jr3_pci_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it)
|
||||
{
|
||||
int result = 0;
|
||||
struct pci_dev *card = NULL;
|
||||
@@ -779,7 +791,7 @@ static int jr3_pci_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
|
||||
if (sizeof(struct jr3_channel) != 0xc00) {
|
||||
printk("sizeof(struct jr3_channel) = %x [expected %x]\n",
|
||||
(unsigned)sizeof(struct jr3_channel), 0xc00);
|
||||
(unsigned)sizeof(struct jr3_channel), 0xc00);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -822,7 +834,7 @@ static int jr3_pci_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
/* Take first available card */
|
||||
break;
|
||||
} else if (opt_bus == card->bus->number &&
|
||||
opt_slot == PCI_SLOT(card->devfn)) {
|
||||
opt_slot == PCI_SLOT(card->devfn)) {
|
||||
/* Take requested card */
|
||||
break;
|
||||
}
|
||||
@@ -843,7 +855,8 @@ static int jr3_pci_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
}
|
||||
|
||||
devpriv->pci_enabled = 1;
|
||||
devpriv->iobase = ioremap(pci_resource_start(card, 0), sizeof(struct jr3_t));
|
||||
devpriv->iobase =
|
||||
ioremap(pci_resource_start(card, 0), sizeof(struct jr3_t));
|
||||
result = alloc_subdevices(dev, devpriv->n_channels);
|
||||
if (result < 0)
|
||||
goto out;
|
||||
@@ -855,7 +868,7 @@ static int jr3_pci_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
dev->subdevices[i].n_chan = 8 * 7 + 2;
|
||||
dev->subdevices[i].insn_read = jr3_pci_ai_insn_read;
|
||||
dev->subdevices[i].private =
|
||||
kzalloc(sizeof(struct jr3_pci_subdev_private), GFP_KERNEL);
|
||||
kzalloc(sizeof(struct jr3_pci_subdev_private), GFP_KERNEL);
|
||||
if (dev->subdevices[i].private) {
|
||||
struct jr3_pci_subdev_private *p;
|
||||
int j;
|
||||
@@ -863,9 +876,9 @@ static int jr3_pci_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
p = dev->subdevices[i].private;
|
||||
p->channel = &devpriv->iobase->channel[i].data;
|
||||
printk("p->channel %p %p (%tx)\n",
|
||||
p->channel, devpriv->iobase,
|
||||
((char *)(p->channel) -
|
||||
(char *)(devpriv->iobase)));
|
||||
p->channel, devpriv->iobase,
|
||||
((char *)(p->channel) -
|
||||
(char *)(devpriv->iobase)));
|
||||
p->channel_no = i;
|
||||
for (j = 0; j < 8; j++) {
|
||||
int k;
|
||||
@@ -875,7 +888,8 @@ static int jr3_pci_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
p->range[j].range.max = 1000000;
|
||||
for (k = 0; k < 7; k++) {
|
||||
p->range_table_list[j + k * 8] =
|
||||
(struct comedi_lrange *) &p->range[j];
|
||||
(struct comedi_lrange *)&p->
|
||||
range[j];
|
||||
p->maxdata_list[j + k * 8] = 0x7fff;
|
||||
}
|
||||
}
|
||||
@@ -884,15 +898,15 @@ static int jr3_pci_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
p->range[8].range.max = 65536;
|
||||
|
||||
p->range_table_list[56] =
|
||||
(struct comedi_lrange *) &p->range[8];
|
||||
(struct comedi_lrange *)&p->range[8];
|
||||
p->range_table_list[57] =
|
||||
(struct comedi_lrange *) &p->range[8];
|
||||
(struct comedi_lrange *)&p->range[8];
|
||||
p->maxdata_list[56] = 0xffff;
|
||||
p->maxdata_list[57] = 0xffff;
|
||||
/* Channel specific range and maxdata */
|
||||
dev->subdevices[i].range_table = 0;
|
||||
dev->subdevices[i].range_table_list =
|
||||
p->range_table_list;
|
||||
p->range_table_list;
|
||||
dev->subdevices[i].maxdata = 0;
|
||||
dev->subdevices[i].maxdata_list = p->maxdata_list;
|
||||
}
|
||||
@@ -922,8 +936,8 @@ static int jr3_pci_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
msleep_interruptible(25);
|
||||
for (i = 0; i < 0x18; i++) {
|
||||
printk("%c",
|
||||
get_u16(&devpriv->iobase->channel[0].data.
|
||||
copyright[i]) >> 8);
|
||||
get_u16(&devpriv->iobase->channel[0].
|
||||
data.copyright[i]) >> 8);
|
||||
}
|
||||
|
||||
/* Start card timer */
|
||||
@@ -939,7 +953,7 @@ static int jr3_pci_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
devpriv->timer.expires = jiffies + msecs_to_jiffies(1000);
|
||||
add_timer(&devpriv->timer);
|
||||
|
||||
out:
|
||||
out:
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,22 +2,22 @@
|
||||
* is 16 bits, but aligned on a 32 bit PCI boundary
|
||||
*/
|
||||
|
||||
static inline u16 get_u16(volatile const u32 *p)
|
||||
static inline u16 get_u16(volatile const u32 * p)
|
||||
{
|
||||
return (u16) readl(p);
|
||||
}
|
||||
|
||||
static inline void set_u16(volatile u32 *p, u16 val)
|
||||
static inline void set_u16(volatile u32 * p, u16 val)
|
||||
{
|
||||
writel(val, p);
|
||||
}
|
||||
|
||||
static inline s16 get_s16(volatile const s32 *p)
|
||||
static inline s16 get_s16(volatile const s32 * p)
|
||||
{
|
||||
return (s16) readl(p);
|
||||
}
|
||||
|
||||
static inline void set_s16(volatile s32 *p, s16 val)
|
||||
static inline void set_s16(volatile s32 * p, s16 val)
|
||||
{
|
||||
writel(val, p);
|
||||
}
|
||||
@@ -304,7 +304,7 @@ struct jr3_channel {
|
||||
/* not set a full scale. */
|
||||
|
||||
struct six_axis_array default_FS; /* offset 0x0068 */
|
||||
s32 reserved3; /* offset 0x006e */
|
||||
s32 reserved3; /* offset 0x006e */
|
||||
|
||||
/* Load_envelope_num is the load envelope number that is currently
|
||||
* in use. This value is set by the user after one of the load
|
||||
@@ -341,7 +341,7 @@ struct jr3_channel {
|
||||
*/
|
||||
|
||||
struct six_axis_array min_full_scale; /* offset 0x0070 */
|
||||
s32 reserved4; /* offset 0x0076 */
|
||||
s32 reserved4; /* offset 0x0076 */
|
||||
|
||||
/* Transform_num is the transform number that is currently in use.
|
||||
* This value is set by the JR3 DSP after the user has used command
|
||||
@@ -354,7 +354,7 @@ struct jr3_channel {
|
||||
/* min_full_scale (pg. 9) for more details. */
|
||||
|
||||
struct six_axis_array max_full_scale; /* offset 0x0078 */
|
||||
s32 reserved5; /* offset 0x007e */
|
||||
s32 reserved5; /* offset 0x007e */
|
||||
|
||||
/* Peak_address is the address of the data which will be monitored
|
||||
* by the peak routine. This value is set by the user. The peak
|
||||
@@ -398,14 +398,14 @@ struct jr3_channel {
|
||||
* offset # command (pg. 34). It can vary between 0 and 15.
|
||||
*/
|
||||
|
||||
s32 offset_num; /* offset 0x008e */
|
||||
s32 offset_num; /* offset 0x008e */
|
||||
|
||||
/* Vect_axes is a bit map showing which of the axes are being used
|
||||
* in the vector calculations. This value is set by the JR3 DSP
|
||||
* after the user has executed the set vector axes command (pg. 37).
|
||||
*/
|
||||
|
||||
u32 vect_axes; /* offset 0x008f */
|
||||
u32 vect_axes; /* offset 0x008f */
|
||||
|
||||
/* Filter0 is the decoupled, unfiltered data from the JR3 sensor.
|
||||
* This data has had the offsets removed.
|
||||
@@ -465,7 +465,7 @@ struct jr3_channel {
|
||||
*/
|
||||
|
||||
s32 near_sat_value; /* offset 0x00e0 */
|
||||
s32 sat_value; /* offset 0x00e1 */
|
||||
s32 sat_value; /* offset 0x00e1 */
|
||||
|
||||
/* Rate_address, rate_divisor & rate_count contain the data used to
|
||||
* control the calculations of the rates. Rate_address is the
|
||||
@@ -486,7 +486,7 @@ struct jr3_channel {
|
||||
|
||||
s32 rate_address; /* offset 0x00e2 */
|
||||
u32 rate_divisor; /* offset 0x00e3 */
|
||||
u32 rate_count; /* offset 0x00e4 */
|
||||
u32 rate_count; /* offset 0x00e4 */
|
||||
|
||||
/* Command_word2 through command_word0 are the locations used to
|
||||
* send commands to the JR3 DSP. Their usage varies with the command
|
||||
@@ -543,14 +543,14 @@ struct jr3_channel {
|
||||
* Issues section on pg. 49 for more details.
|
||||
*/
|
||||
|
||||
u32 count_x; /* offset 0x00ef */
|
||||
u32 count_x; /* offset 0x00ef */
|
||||
|
||||
/* Warnings & errors contain the warning and error bits
|
||||
* respectively. The format of these two words is discussed on page
|
||||
* 21 under the headings warnings_bits and error_bits.
|
||||
*/
|
||||
|
||||
u32 warnings; /* offset 0x00f0 */
|
||||
u32 warnings; /* offset 0x00f0 */
|
||||
u32 errors; /* offset 0x00f1 */
|
||||
|
||||
/* Threshold_bits is a word containing the bits that are set by the
|
||||
@@ -565,7 +565,7 @@ struct jr3_channel {
|
||||
* description for cal_crc_bad (pg. 21) for more information.
|
||||
*/
|
||||
|
||||
s32 last_CRC; /* offset 0x00f3 */
|
||||
s32 last_CRC; /* offset 0x00f3 */
|
||||
|
||||
/* EEProm_ver_no contains the version number of the sensor EEProm.
|
||||
* EEProm version numbers can vary between 0 and 255.
|
||||
@@ -591,16 +591,16 @@ struct jr3_channel {
|
||||
* different sensor configurations.
|
||||
*/
|
||||
|
||||
u32 serial_no; /* offset 0x00f8 */
|
||||
u32 model_no; /* offset 0x00f9 */
|
||||
u32 serial_no; /* offset 0x00f8 */
|
||||
u32 model_no; /* offset 0x00f9 */
|
||||
|
||||
/* Cal_day & cal_year are the sensor calibration date. Day is the
|
||||
* day of the year, with January 1 being 1, and December 31, being
|
||||
* 366 for leap years.
|
||||
*/
|
||||
|
||||
s32 cal_day; /* offset 0x00fa */
|
||||
s32 cal_year; /* offset 0x00fb */
|
||||
s32 cal_day; /* offset 0x00fa */
|
||||
s32 cal_year; /* offset 0x00fb */
|
||||
|
||||
/* Units is an enumerated read only value defining the engineering
|
||||
* units used in the sensor full scale. The meanings of particular
|
||||
@@ -627,7 +627,7 @@ struct jr3_channel {
|
||||
|
||||
u32 units; /* offset 0x00fc */
|
||||
s32 bits; /* offset 0x00fd */
|
||||
s32 channels; /* offset 0x00fe */
|
||||
s32 channels; /* offset 0x00fe */
|
||||
|
||||
/* Thickness specifies the overall thickness of the sensor from
|
||||
* flange to flange. The engineering units for this value are
|
||||
@@ -636,7 +636,7 @@ struct jr3_channel {
|
||||
* transformation from the center of the sensor to either flange.
|
||||
*/
|
||||
|
||||
s32 thickness; /* offset 0x00ff */
|
||||
s32 thickness; /* offset 0x00ff */
|
||||
|
||||
/* Load_envelopes is a table containing the load envelope
|
||||
* descriptions. There are 16 possible load envelope slots in the
|
||||
|
||||
@@ -52,9 +52,10 @@ static int cnt_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int cnt_detach(struct comedi_device *dev);
|
||||
|
||||
static DEFINE_PCI_DEVICE_TABLE(cnt_pci_table) = {
|
||||
{PCI_VENDOR_ID_KOLTER, CNT_CARD_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
|
||||
0},
|
||||
{0}
|
||||
{
|
||||
PCI_VENDOR_ID_KOLTER, CNT_CARD_DEVICE_ID, PCI_ANY_ID,
|
||||
PCI_ANY_ID, 0, 0, 0}, {
|
||||
0}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, cnt_pci_table);
|
||||
@@ -69,13 +70,12 @@ struct cnt_board_struct {
|
||||
int cnt_bits;
|
||||
};
|
||||
|
||||
|
||||
static const struct cnt_board_struct cnt_boards[] = {
|
||||
{
|
||||
.name = CNT_DRIVER_NAME,
|
||||
.device_id = CNT_CARD_DEVICE_ID,
|
||||
.cnt_channel_nbr = 3,
|
||||
.cnt_bits = 24}
|
||||
.name = CNT_DRIVER_NAME,
|
||||
.device_id = CNT_CARD_DEVICE_ID,
|
||||
.cnt_channel_nbr = 3,
|
||||
.cnt_bits = 24}
|
||||
};
|
||||
|
||||
#define cnt_board_nbr (sizeof(cnt_boards)/sizeof(struct cnt_board_struct))
|
||||
@@ -87,7 +87,6 @@ struct cnt_device_private {
|
||||
struct pci_dev *pcidev;
|
||||
};
|
||||
|
||||
|
||||
#define devpriv ((struct cnt_device_private *)dev->private)
|
||||
|
||||
static struct comedi_driver cnt_driver = {
|
||||
@@ -104,18 +103,19 @@ COMEDI_PCI_INITCLEANUP(cnt_driver, cnt_pci_table);
|
||||
/* This should be used only for resetting the counters; maybe it is better
|
||||
to make a special command 'reset'. */
|
||||
static int cnt_winsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
|
||||
outb((unsigned char)((data[0] >> 24) & 0xff),
|
||||
dev->iobase + chan * 0x20 + 0x10);
|
||||
dev->iobase + chan * 0x20 + 0x10);
|
||||
outb((unsigned char)((data[0] >> 16) & 0xff),
|
||||
dev->iobase + chan * 0x20 + 0x0c);
|
||||
dev->iobase + chan * 0x20 + 0x0c);
|
||||
outb((unsigned char)((data[0] >> 8) & 0xff),
|
||||
dev->iobase + chan * 0x20 + 0x08);
|
||||
dev->iobase + chan * 0x20 + 0x08);
|
||||
outb((unsigned char)((data[0] >> 0) & 0xff),
|
||||
dev->iobase + chan * 0x20 + 0x04);
|
||||
dev->iobase + chan * 0x20 + 0x04);
|
||||
|
||||
/* return the number of samples written */
|
||||
return 1;
|
||||
@@ -124,7 +124,8 @@ static int cnt_winsn(struct comedi_device *dev,
|
||||
/*-- counter read -----------------------------------------------------------*/
|
||||
|
||||
static int cnt_rinsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
unsigned char a0, a1, a2, a3, a4;
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
@@ -140,7 +141,7 @@ static int cnt_rinsn(struct comedi_device *dev,
|
||||
if (a4 > 0)
|
||||
result = result - s->maxdata;
|
||||
|
||||
*data = (unsigned int) result;
|
||||
*data = (unsigned int)result;
|
||||
|
||||
/* return the number of samples read */
|
||||
return 1;
|
||||
@@ -163,49 +164,51 @@ static int cnt_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
|
||||
/* Probe the device to determine what device in the series it is. */
|
||||
for (pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
|
||||
pci_device != NULL;
|
||||
pci_device =
|
||||
pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_device)) {
|
||||
pci_device != NULL;
|
||||
pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_device)) {
|
||||
if (pci_device->vendor == PCI_VENDOR_ID_KOLTER) {
|
||||
for (i = 0; i < cnt_board_nbr; i++) {
|
||||
if (cnt_boards[i].device_id ==
|
||||
pci_device->device) {
|
||||
pci_device->device) {
|
||||
/* was a particular bus/slot requested? */
|
||||
if ((it->options[0] != 0)
|
||||
|| (it->options[1] != 0)) {
|
||||
|| (it->options[1] != 0)) {
|
||||
/* are we on the wrong bus/slot? */
|
||||
if (pci_device->bus->number !=
|
||||
it->options[0]
|
||||
|| PCI_SLOT(pci_device->
|
||||
devfn) !=
|
||||
it->options[1]) {
|
||||
it->options[0]
|
||||
||
|
||||
PCI_SLOT(pci_device->devfn)
|
||||
!= it->options[1]) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
dev->board_ptr = cnt_boards + i;
|
||||
board = (struct cnt_board_struct *) dev->
|
||||
board_ptr;
|
||||
board =
|
||||
(struct cnt_board_struct *)
|
||||
dev->board_ptr;
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
printk("comedi%d: no supported board found! (req. bus/slot: %d/%d)\n",
|
||||
dev->minor, it->options[0], it->options[1]);
|
||||
dev->minor, it->options[0], it->options[1]);
|
||||
return -EIO;
|
||||
|
||||
found:
|
||||
found:
|
||||
printk("comedi%d: found %s at PCI bus %d, slot %d\n", dev->minor,
|
||||
board->name, pci_device->bus->number,
|
||||
PCI_SLOT(pci_device->devfn));
|
||||
board->name, pci_device->bus->number,
|
||||
PCI_SLOT(pci_device->devfn));
|
||||
devpriv->pcidev = pci_device;
|
||||
dev->board_name = board->name;
|
||||
|
||||
/* enable PCI device and request regions */
|
||||
error = comedi_pci_enable(pci_device, CNT_DRIVER_NAME);
|
||||
if (error < 0) {
|
||||
printk("comedi%d: failed to enable PCI device and request regions!\n", dev->minor);
|
||||
printk
|
||||
("comedi%d: failed to enable PCI device and request regions!\n",
|
||||
dev->minor);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -151,46 +151,47 @@ static int me_detach(struct comedi_device *dev);
|
||||
static const struct comedi_lrange me2000_ai_range = {
|
||||
8,
|
||||
{
|
||||
BIP_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(2.5),
|
||||
BIP_RANGE(1.25),
|
||||
UNI_RANGE(10),
|
||||
UNI_RANGE(5),
|
||||
UNI_RANGE(2.5),
|
||||
UNI_RANGE(1.25)
|
||||
}
|
||||
BIP_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(2.5),
|
||||
BIP_RANGE(1.25),
|
||||
UNI_RANGE(10),
|
||||
UNI_RANGE(5),
|
||||
UNI_RANGE(2.5),
|
||||
UNI_RANGE(1.25)
|
||||
}
|
||||
};
|
||||
|
||||
static const struct comedi_lrange me2600_ai_range = {
|
||||
8,
|
||||
{
|
||||
BIP_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(2.5),
|
||||
BIP_RANGE(1.25),
|
||||
UNI_RANGE(10),
|
||||
UNI_RANGE(5),
|
||||
UNI_RANGE(2.5),
|
||||
UNI_RANGE(1.25)
|
||||
}
|
||||
BIP_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
BIP_RANGE(2.5),
|
||||
BIP_RANGE(1.25),
|
||||
UNI_RANGE(10),
|
||||
UNI_RANGE(5),
|
||||
UNI_RANGE(2.5),
|
||||
UNI_RANGE(1.25)
|
||||
}
|
||||
};
|
||||
|
||||
static const struct comedi_lrange me2600_ao_range = {
|
||||
3,
|
||||
{
|
||||
BIP_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
UNI_RANGE(10)
|
||||
}
|
||||
BIP_RANGE(10),
|
||||
BIP_RANGE(5),
|
||||
UNI_RANGE(10)
|
||||
}
|
||||
};
|
||||
|
||||
static DEFINE_PCI_DEVICE_TABLE(me_pci_table) = {
|
||||
{PCI_VENDOR_ID_MEILHAUS, ME2600_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
|
||||
0},
|
||||
{PCI_VENDOR_ID_MEILHAUS, ME2000_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
|
||||
0},
|
||||
{0}
|
||||
{
|
||||
PCI_VENDOR_ID_MEILHAUS, ME2600_DEVICE_ID, PCI_ANY_ID,
|
||||
PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_MEILHAUS, ME2000_DEVICE_ID, PCI_ANY_ID,
|
||||
PCI_ANY_ID, 0, 0, 0}, {
|
||||
0}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, me_pci_table);
|
||||
@@ -212,48 +213,48 @@ struct me_board {
|
||||
|
||||
static const struct me_board me_boards[] = {
|
||||
{
|
||||
/* -- ME-2600i -- */
|
||||
.name = ME_DRIVER_NAME,
|
||||
.device_id = ME2600_DEVICE_ID,
|
||||
/* Analog Output */
|
||||
.ao_channel_nbr = 4,
|
||||
.ao_resolution = 12,
|
||||
.ao_resolution_mask = 0x0fff,
|
||||
.ao_range_list = &me2600_ao_range,
|
||||
.ai_channel_nbr = 16,
|
||||
/* Analog Input */
|
||||
.ai_resolution = 12,
|
||||
.ai_resolution_mask = 0x0fff,
|
||||
.ai_range_list = &me2600_ai_range,
|
||||
.dio_channel_nbr = 32,
|
||||
},
|
||||
/* -- ME-2600i -- */
|
||||
.name = ME_DRIVER_NAME,
|
||||
.device_id = ME2600_DEVICE_ID,
|
||||
/* Analog Output */
|
||||
.ao_channel_nbr = 4,
|
||||
.ao_resolution = 12,
|
||||
.ao_resolution_mask = 0x0fff,
|
||||
.ao_range_list = &me2600_ao_range,
|
||||
.ai_channel_nbr = 16,
|
||||
/* Analog Input */
|
||||
.ai_resolution = 12,
|
||||
.ai_resolution_mask = 0x0fff,
|
||||
.ai_range_list = &me2600_ai_range,
|
||||
.dio_channel_nbr = 32,
|
||||
},
|
||||
{
|
||||
/* -- ME-2000i -- */
|
||||
.name = ME_DRIVER_NAME,
|
||||
.device_id = ME2000_DEVICE_ID,
|
||||
/* Analog Output */
|
||||
.ao_channel_nbr = 0,
|
||||
.ao_resolution = 0,
|
||||
.ao_resolution_mask = 0,
|
||||
.ao_range_list = NULL,
|
||||
.ai_channel_nbr = 16,
|
||||
/* Analog Input */
|
||||
.ai_resolution = 12,
|
||||
.ai_resolution_mask = 0x0fff,
|
||||
.ai_range_list = &me2000_ai_range,
|
||||
.dio_channel_nbr = 32,
|
||||
}
|
||||
/* -- ME-2000i -- */
|
||||
.name = ME_DRIVER_NAME,
|
||||
.device_id = ME2000_DEVICE_ID,
|
||||
/* Analog Output */
|
||||
.ao_channel_nbr = 0,
|
||||
.ao_resolution = 0,
|
||||
.ao_resolution_mask = 0,
|
||||
.ao_range_list = NULL,
|
||||
.ai_channel_nbr = 16,
|
||||
/* Analog Input */
|
||||
.ai_resolution = 12,
|
||||
.ai_resolution_mask = 0x0fff,
|
||||
.ai_range_list = &me2000_ai_range,
|
||||
.dio_channel_nbr = 32,
|
||||
}
|
||||
};
|
||||
|
||||
#define me_board_nbr (sizeof(me_boards)/sizeof(struct me_board))
|
||||
|
||||
|
||||
static struct comedi_driver me_driver = {
|
||||
.driver_name = ME_DRIVER_NAME,
|
||||
.module = THIS_MODULE,
|
||||
.attach = me_attach,
|
||||
.detach = me_detach,
|
||||
.driver_name = ME_DRIVER_NAME,
|
||||
.module = THIS_MODULE,
|
||||
.attach = me_attach,
|
||||
.detach = me_detach,
|
||||
};
|
||||
|
||||
COMEDI_PCI_INITCLEANUP(me_driver, me_pci_table);
|
||||
|
||||
/* Private data structure */
|
||||
@@ -292,7 +293,8 @@ static inline void sleep(unsigned sec)
|
||||
*
|
||||
* ------------------------------------------------------------------
|
||||
*/
|
||||
static int me_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
static int me_dio_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int bits;
|
||||
@@ -305,7 +307,7 @@ static int me_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice
|
||||
/* Enable Port A */
|
||||
dev_private->control_2 |= ENABLE_PORT_A;
|
||||
writew(dev_private->control_2,
|
||||
dev_private->me_regbase + ME_CONTROL_2);
|
||||
dev_private->me_regbase + ME_CONTROL_2);
|
||||
} else { /* Port B in use */
|
||||
|
||||
bits = 0xffff0000;
|
||||
@@ -313,7 +315,7 @@ static int me_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice
|
||||
/* Enable Port B */
|
||||
dev_private->control_2 |= ENABLE_PORT_B;
|
||||
writew(dev_private->control_2,
|
||||
dev_private->me_regbase + ME_CONTROL_2);
|
||||
dev_private->me_regbase + ME_CONTROL_2);
|
||||
}
|
||||
|
||||
if (data[0]) {
|
||||
@@ -328,7 +330,8 @@ static int me_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice
|
||||
}
|
||||
|
||||
/* Digital instant input/outputs */
|
||||
static int me_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
static int me_dio_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
unsigned int mask = data[0];
|
||||
@@ -338,7 +341,7 @@ static int me_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *
|
||||
mask &= s->io_bits;
|
||||
if (mask & 0x0000ffff) { /* Port A */
|
||||
writew((s->state & 0xffff),
|
||||
dev_private->me_regbase + ME_DIO_PORT_A);
|
||||
dev_private->me_regbase + ME_DIO_PORT_A);
|
||||
} else {
|
||||
data[1] &= ~0x0000ffff;
|
||||
data[1] |= readw(dev_private->me_regbase + ME_DIO_PORT_A);
|
||||
@@ -346,7 +349,7 @@ static int me_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *
|
||||
|
||||
if (mask & 0xffff0000) { /* Port B */
|
||||
writew(((s->state >> 16) & 0xffff),
|
||||
dev_private->me_regbase + ME_DIO_PORT_B);
|
||||
dev_private->me_regbase + ME_DIO_PORT_B);
|
||||
} else {
|
||||
data[1] &= ~0xffff0000;
|
||||
data[1] |= readw(dev_private->me_regbase + ME_DIO_PORT_B) << 16;
|
||||
@@ -364,7 +367,8 @@ static int me_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *
|
||||
*/
|
||||
|
||||
/* Analog instant input */
|
||||
static int me_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *subdevice,
|
||||
static int me_ai_insn_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *subdevice,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
unsigned short value;
|
||||
@@ -414,8 +418,8 @@ static int me_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s
|
||||
/* get value from ADC fifo */
|
||||
if (i) {
|
||||
data[0] =
|
||||
(readw(dev_private->me_regbase +
|
||||
ME_READ_AD_FIFO) ^ 0x800) & 0x0FFF;
|
||||
(readw(dev_private->me_regbase +
|
||||
ME_READ_AD_FIFO) ^ 0x800) & 0x0FFF;
|
||||
} else {
|
||||
printk(KERN_ERR "comedi%d: Cannot get single value\n",
|
||||
dev->minor);
|
||||
@@ -450,14 +454,15 @@ static int me_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
}
|
||||
|
||||
/* Test analog input command */
|
||||
static int me_ai_do_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd)
|
||||
static int me_ai_do_cmd_test(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_cmd *cmd)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Analog input command */
|
||||
static int me_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *subdevice)
|
||||
static int me_ai_do_cmd(struct comedi_device *dev,
|
||||
struct comedi_subdevice *subdevice)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -471,7 +476,8 @@ static int me_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *subd
|
||||
*/
|
||||
|
||||
/* Analog instant output */
|
||||
static int me_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
static int me_ao_insn_write(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int chan;
|
||||
@@ -495,13 +501,13 @@ static int me_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *
|
||||
dev_private->dac_control &= ~(0x0880 >> chan);
|
||||
if (rang == 0)
|
||||
dev_private->dac_control |=
|
||||
((DAC_BIPOLAR_A | DAC_GAIN_1_A) >> chan);
|
||||
((DAC_BIPOLAR_A | DAC_GAIN_1_A) >> chan);
|
||||
else if (rang == 1)
|
||||
dev_private->dac_control |=
|
||||
((DAC_BIPOLAR_A | DAC_GAIN_0_A) >> chan);
|
||||
((DAC_BIPOLAR_A | DAC_GAIN_0_A) >> chan);
|
||||
}
|
||||
writew(dev_private->dac_control,
|
||||
dev_private->me_regbase + ME_DAC_CONTROL);
|
||||
dev_private->me_regbase + ME_DAC_CONTROL);
|
||||
|
||||
/* Update dac-control register */
|
||||
readw(dev_private->me_regbase + ME_DAC_CONTROL_UPDATE);
|
||||
@@ -510,7 +516,7 @@ static int me_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *
|
||||
for (i = 0; i < insn->n; i++) {
|
||||
chan = CR_CHAN((&insn->chanspec)[i]);
|
||||
writew((data[0] & s->maxdata),
|
||||
dev_private->me_regbase + ME_DAC_DATA_A + (chan << 1));
|
||||
dev_private->me_regbase + ME_DAC_DATA_A + (chan << 1));
|
||||
dev_private->ao_readback[chan] = (data[0] & s->maxdata);
|
||||
}
|
||||
|
||||
@@ -521,14 +527,15 @@ static int me_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *
|
||||
}
|
||||
|
||||
/* Analog output readback */
|
||||
static int me_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int me_ao_insn_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < insn->n; i++) {
|
||||
data[i] =
|
||||
dev_private->ao_readback[CR_CHAN((&insn->chanspec)[i])];
|
||||
dev_private->ao_readback[CR_CHAN((&insn->chanspec)[i])];
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -575,9 +582,9 @@ static int me2600_xilinx_download(struct comedi_device *dev,
|
||||
if (length < 16)
|
||||
return -EINVAL;
|
||||
file_length = (((unsigned int)me2600_firmware[0] & 0xff) << 24) +
|
||||
(((unsigned int)me2600_firmware[1] & 0xff) << 16) +
|
||||
(((unsigned int)me2600_firmware[2] & 0xff) << 8) +
|
||||
((unsigned int)me2600_firmware[3] & 0xff);
|
||||
(((unsigned int)me2600_firmware[1] & 0xff) << 16) +
|
||||
(((unsigned int)me2600_firmware[2] & 0xff) << 8) +
|
||||
((unsigned int)me2600_firmware[3] & 0xff);
|
||||
|
||||
/*
|
||||
* Loop for writing firmware byte by byte to xilinx
|
||||
@@ -585,7 +592,7 @@ static int me2600_xilinx_download(struct comedi_device *dev,
|
||||
*/
|
||||
for (i = 0; i < file_length; i++)
|
||||
writeb((me2600_firmware[16 + i] & 0xff),
|
||||
dev_private->me_regbase + 0x0);
|
||||
dev_private->me_regbase + 0x0);
|
||||
|
||||
/* Write 5 dummy values to xilinx */
|
||||
for (i = 0; i < 5; i++)
|
||||
@@ -653,33 +660,32 @@ static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
|
||||
/* Probe the device to determine what device in the series it is. */
|
||||
for (pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
|
||||
pci_device != NULL;
|
||||
pci_device =
|
||||
pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_device)) {
|
||||
pci_device != NULL;
|
||||
pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_device)) {
|
||||
if (pci_device->vendor == PCI_VENDOR_ID_MEILHAUS) {
|
||||
for (i = 0; i < me_board_nbr; i++) {
|
||||
if (me_boards[i].device_id ==
|
||||
pci_device->device) {
|
||||
pci_device->device) {
|
||||
/*
|
||||
* was a particular bus/slot requested?
|
||||
*/
|
||||
if ((it->options[0] != 0)
|
||||
|| (it->options[1] != 0)) {
|
||||
|| (it->options[1] != 0)) {
|
||||
/*
|
||||
* are we on the wrong bus/slot?
|
||||
*/
|
||||
if (pci_device->bus->number !=
|
||||
it->options[0]
|
||||
|| PCI_SLOT(pci_device->
|
||||
devfn) !=
|
||||
it->options[1]) {
|
||||
it->options[0]
|
||||
||
|
||||
PCI_SLOT(pci_device->devfn)
|
||||
!= it->options[1]) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
dev->board_ptr = me_boards + i;
|
||||
board = (struct me_board *) dev->
|
||||
board_ptr;
|
||||
board =
|
||||
(struct me_board *)dev->board_ptr;
|
||||
dev_private->pci_device = pci_device;
|
||||
goto found;
|
||||
}
|
||||
@@ -694,8 +700,8 @@ static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
|
||||
found:
|
||||
printk(KERN_INFO "comedi%d: found %s at PCI bus %d, slot %d\n",
|
||||
dev->minor, me_boards[i].name,
|
||||
pci_device->bus->number, PCI_SLOT(pci_device->devfn));
|
||||
dev->minor, me_boards[i].name,
|
||||
pci_device->bus->number, PCI_SLOT(pci_device->devfn));
|
||||
|
||||
/* Enable PCI device and request PCI regions */
|
||||
if (comedi_pci_enable(pci_device, ME_DRIVER_NAME) < 0) {
|
||||
@@ -711,7 +717,7 @@ static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
plx_regbase_tmp = pci_resource_start(pci_device, 0);
|
||||
plx_regbase_size_tmp = pci_resource_len(pci_device, 0);
|
||||
dev_private->plx_regbase =
|
||||
ioremap(plx_regbase_tmp, plx_regbase_size_tmp);
|
||||
ioremap(plx_regbase_tmp, plx_regbase_size_tmp);
|
||||
dev_private->plx_regbase_size = plx_regbase_size_tmp;
|
||||
if (!dev_private->plx_regbase) {
|
||||
printk("comedi%d: Failed to remap I/O memory\n", dev->minor);
|
||||
@@ -736,18 +742,21 @@ static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
swap_regbase_tmp = regbase_tmp;
|
||||
|
||||
result = pci_write_config_dword(pci_device,
|
||||
PCI_BASE_ADDRESS_0, plx_regbase_tmp);
|
||||
PCI_BASE_ADDRESS_0,
|
||||
plx_regbase_tmp);
|
||||
if (result != PCIBIOS_SUCCESSFUL)
|
||||
return -EIO;
|
||||
|
||||
result = pci_write_config_dword(pci_device,
|
||||
PCI_BASE_ADDRESS_5, swap_regbase_tmp);
|
||||
PCI_BASE_ADDRESS_5,
|
||||
swap_regbase_tmp);
|
||||
if (result != PCIBIOS_SUCCESSFUL)
|
||||
return -EIO;
|
||||
} else {
|
||||
plx_regbase_tmp -= 0x80;
|
||||
result = pci_write_config_dword(pci_device,
|
||||
PCI_BASE_ADDRESS_0, plx_regbase_tmp);
|
||||
PCI_BASE_ADDRESS_0,
|
||||
plx_regbase_tmp);
|
||||
if (result != PCIBIOS_SUCCESSFUL)
|
||||
return -EIO;
|
||||
}
|
||||
@@ -822,7 +831,8 @@ static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
subdevice->insn_config = me_dio_insn_config;
|
||||
subdevice->io_bits = 0;
|
||||
|
||||
printk(KERN_INFO "comedi%d: "ME_DRIVER_NAME" attached.\n", dev->minor);
|
||||
printk(KERN_INFO "comedi%d: " ME_DRIVER_NAME " attached.\n",
|
||||
dev->minor);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -73,8 +73,8 @@ void mite_init(void)
|
||||
struct mite_struct *mite;
|
||||
|
||||
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)) {
|
||||
pcidev != NULL;
|
||||
pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
|
||||
if (pcidev->vendor == PCI_VENDOR_ID_NATINST) {
|
||||
unsigned i;
|
||||
|
||||
@@ -99,14 +99,19 @@ void mite_init(void)
|
||||
|
||||
static void dump_chip_signature(u32 csigr_bits)
|
||||
{
|
||||
printk("mite: version = %i, type = %i, mite mode = %i, interface mode = %i\n", mite_csigr_version(csigr_bits), mite_csigr_type(csigr_bits), mite_csigr_mmode(csigr_bits), mite_csigr_imode(csigr_bits));
|
||||
printk("mite: num channels = %i, write post fifo depth = %i, wins = %i, iowins = %i\n", mite_csigr_dmac(csigr_bits), mite_csigr_wpdep(csigr_bits), mite_csigr_wins(csigr_bits), mite_csigr_iowins(csigr_bits));
|
||||
printk
|
||||
("mite: version = %i, type = %i, mite mode = %i, interface mode = %i\n",
|
||||
mite_csigr_version(csigr_bits), mite_csigr_type(csigr_bits),
|
||||
mite_csigr_mmode(csigr_bits), mite_csigr_imode(csigr_bits));
|
||||
printk
|
||||
("mite: num channels = %i, write post fifo depth = %i, wins = %i, iowins = %i\n",
|
||||
mite_csigr_dmac(csigr_bits), mite_csigr_wpdep(csigr_bits),
|
||||
mite_csigr_wins(csigr_bits), mite_csigr_iowins(csigr_bits));
|
||||
}
|
||||
|
||||
unsigned mite_fifo_size(struct mite_struct *mite, unsigned channel)
|
||||
{
|
||||
unsigned fcr_bits = readl(mite->mite_io_addr +
|
||||
MITE_FCR(channel));
|
||||
unsigned fcr_bits = readl(mite->mite_io_addr + MITE_FCR(channel));
|
||||
unsigned empty_count = (fcr_bits >> 16) & 0xff;
|
||||
unsigned full_count = fcr_bits & 0xff;
|
||||
return empty_count + full_count;
|
||||
@@ -134,7 +139,7 @@ int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1)
|
||||
return -ENOMEM;
|
||||
}
|
||||
printk("MITE:0x%08llx mapped to %p ",
|
||||
(unsigned long long)mite->mite_phys_addr, mite->mite_io_addr);
|
||||
(unsigned long long)mite->mite_phys_addr, mite->mite_io_addr);
|
||||
|
||||
addr = pci_resource_start(mite->pcidev, 1);
|
||||
mite->daq_phys_addr = addr;
|
||||
@@ -146,19 +151,18 @@ int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1)
|
||||
return -ENOMEM;
|
||||
}
|
||||
printk("DAQ:0x%08llx mapped to %p\n",
|
||||
(unsigned long long)mite->daq_phys_addr, mite->daq_io_addr);
|
||||
(unsigned long long)mite->daq_phys_addr, mite->daq_io_addr);
|
||||
|
||||
if (use_iodwbsr_1) {
|
||||
writel(0, mite->mite_io_addr + MITE_IODWBSR);
|
||||
printk("mite: using I/O Window Base Size register 1\n");
|
||||
writel(mite->
|
||||
daq_phys_addr | WENAB |
|
||||
MITE_IODWBSR_1_WSIZE_bits(length),
|
||||
mite->mite_io_addr + MITE_IODWBSR_1);
|
||||
writel(mite->daq_phys_addr | WENAB |
|
||||
MITE_IODWBSR_1_WSIZE_bits(length),
|
||||
mite->mite_io_addr + MITE_IODWBSR_1);
|
||||
writel(0, mite->mite_io_addr + MITE_IODWCR_1);
|
||||
} else {
|
||||
writel(mite->daq_phys_addr | WENAB,
|
||||
mite->mite_io_addr + MITE_IODWBSR);
|
||||
mite->mite_io_addr + MITE_IODWBSR);
|
||||
}
|
||||
/* make sure dma bursts work. I got this from running a bus analyzer
|
||||
on a pxi-6281 and a pxi-6713. 6713 powered up with register value
|
||||
@@ -167,15 +171,17 @@ int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1)
|
||||
then does a bitwise-or of 0x600 with it and writes it back.
|
||||
*/
|
||||
unknown_dma_burst_bits =
|
||||
readl(mite->mite_io_addr + MITE_UNKNOWN_DMA_BURST_REG);
|
||||
readl(mite->mite_io_addr + MITE_UNKNOWN_DMA_BURST_REG);
|
||||
unknown_dma_burst_bits |= UNKNOWN_DMA_BURST_ENABLE_BITS;
|
||||
writel(unknown_dma_burst_bits,
|
||||
mite->mite_io_addr + MITE_UNKNOWN_DMA_BURST_REG);
|
||||
mite->mite_io_addr + MITE_UNKNOWN_DMA_BURST_REG);
|
||||
|
||||
csigr_bits = readl(mite->mite_io_addr + MITE_CSIGR);
|
||||
mite->num_channels = mite_csigr_dmac(csigr_bits);
|
||||
if (mite->num_channels > MAX_MITE_DMA_CHANNELS) {
|
||||
printk("mite: bug? chip claims to have %i dma channels. Setting to %i.\n", mite->num_channels, MAX_MITE_DMA_CHANNELS);
|
||||
printk
|
||||
("mite: bug? chip claims to have %i dma channels. Setting to %i.\n",
|
||||
mite->num_channels, MAX_MITE_DMA_CHANNELS);
|
||||
mite->num_channels = MAX_MITE_DMA_CHANNELS;
|
||||
}
|
||||
dump_chip_signature(csigr_bits);
|
||||
@@ -183,9 +189,9 @@ int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1)
|
||||
writel(CHOR_DMARESET, mite->mite_io_addr + MITE_CHOR(i));
|
||||
/* disable interrupts */
|
||||
writel(CHCR_CLR_DMA_IE | CHCR_CLR_LINKP_IE | CHCR_CLR_SAR_IE |
|
||||
CHCR_CLR_DONE_IE | CHCR_CLR_MRDY_IE | CHCR_CLR_DRDY_IE |
|
||||
CHCR_CLR_LC_IE | CHCR_CLR_CONT_RB_IE,
|
||||
mite->mite_io_addr + MITE_CHCR(i));
|
||||
CHCR_CLR_DONE_IE | CHCR_CLR_MRDY_IE | CHCR_CLR_DRDY_IE |
|
||||
CHCR_CLR_LC_IE | CHCR_CLR_CONT_RB_IE,
|
||||
mite->mite_io_addr + MITE_CHCR(i));
|
||||
}
|
||||
mite->fifo_size = mite_fifo_size(mite, 0);
|
||||
printk("mite: fifo size is %i.\n", mite->fifo_size);
|
||||
@@ -250,8 +256,10 @@ void mite_list_devices(void)
|
||||
}
|
||||
|
||||
struct mite_channel *mite_request_channel_in_range(struct mite_struct *mite,
|
||||
struct mite_dma_descriptor_ring *ring, unsigned min_channel,
|
||||
unsigned max_channel)
|
||||
struct
|
||||
mite_dma_descriptor_ring
|
||||
*ring, unsigned min_channel,
|
||||
unsigned max_channel)
|
||||
{
|
||||
int i;
|
||||
unsigned long flags;
|
||||
@@ -284,10 +292,10 @@ void mite_release_channel(struct mite_channel *mite_chan)
|
||||
/* disable all channel's interrupts (do it after disarm/reset so
|
||||
MITE_CHCR reg isn't changed while dma is still active!) */
|
||||
writel(CHCR_CLR_DMA_IE | CHCR_CLR_LINKP_IE |
|
||||
CHCR_CLR_SAR_IE | CHCR_CLR_DONE_IE |
|
||||
CHCR_CLR_MRDY_IE | CHCR_CLR_DRDY_IE |
|
||||
CHCR_CLR_LC_IE | CHCR_CLR_CONT_RB_IE,
|
||||
mite->mite_io_addr + MITE_CHCR(mite_chan->channel));
|
||||
CHCR_CLR_SAR_IE | CHCR_CLR_DONE_IE |
|
||||
CHCR_CLR_MRDY_IE | CHCR_CLR_DRDY_IE |
|
||||
CHCR_CLR_LC_IE | CHCR_CLR_CONT_RB_IE,
|
||||
mite->mite_io_addr + MITE_CHCR(mite_chan->channel));
|
||||
mite->channel_allocated[mite_chan->channel] = 0;
|
||||
mite_chan->ring = NULL;
|
||||
mmiowb();
|
||||
@@ -317,15 +325,18 @@ void mite_dma_arm(struct mite_channel *mite_chan)
|
||||
|
||||
/**************************************/
|
||||
|
||||
int mite_buf_change(struct mite_dma_descriptor_ring *ring, struct comedi_async * async)
|
||||
int mite_buf_change(struct mite_dma_descriptor_ring *ring,
|
||||
struct comedi_async *async)
|
||||
{
|
||||
unsigned int n_links;
|
||||
int i;
|
||||
|
||||
if (ring->descriptors) {
|
||||
dma_free_coherent(ring->hw_dev,
|
||||
ring->n_links * sizeof(struct mite_dma_descriptor),
|
||||
ring->descriptors, ring->descriptors_dma_addr);
|
||||
ring->n_links *
|
||||
sizeof(struct mite_dma_descriptor),
|
||||
ring->descriptors,
|
||||
ring->descriptors_dma_addr);
|
||||
}
|
||||
ring->descriptors = NULL;
|
||||
ring->descriptors_dma_addr = 0;
|
||||
@@ -339,9 +350,9 @@ int mite_buf_change(struct mite_dma_descriptor_ring *ring, struct comedi_async *
|
||||
MDPRINTK("ring->hw_dev=%p, n_links=0x%04x\n", ring->hw_dev, n_links);
|
||||
|
||||
ring->descriptors =
|
||||
dma_alloc_coherent(ring->hw_dev,
|
||||
n_links * sizeof(struct mite_dma_descriptor),
|
||||
&ring->descriptors_dma_addr, GFP_KERNEL);
|
||||
dma_alloc_coherent(ring->hw_dev,
|
||||
n_links * sizeof(struct mite_dma_descriptor),
|
||||
&ring->descriptors_dma_addr, GFP_KERNEL);
|
||||
if (!ring->descriptors) {
|
||||
printk("mite: ring buffer allocation failed\n");
|
||||
return -ENOMEM;
|
||||
@@ -351,13 +362,14 @@ int mite_buf_change(struct mite_dma_descriptor_ring *ring, struct comedi_async *
|
||||
for (i = 0; i < n_links; i++) {
|
||||
ring->descriptors[i].count = cpu_to_le32(PAGE_SIZE);
|
||||
ring->descriptors[i].addr =
|
||||
cpu_to_le32(async->buf_page_list[i].dma_addr);
|
||||
cpu_to_le32(async->buf_page_list[i].dma_addr);
|
||||
ring->descriptors[i].next =
|
||||
cpu_to_le32(ring->descriptors_dma_addr + (i +
|
||||
1) * sizeof(struct mite_dma_descriptor));
|
||||
cpu_to_le32(ring->descriptors_dma_addr + (i +
|
||||
1) *
|
||||
sizeof(struct mite_dma_descriptor));
|
||||
}
|
||||
ring->descriptors[n_links - 1].next =
|
||||
cpu_to_le32(ring->descriptors_dma_addr);
|
||||
cpu_to_le32(ring->descriptors_dma_addr);
|
||||
/* barrier is meant to insure that all the writes to the dma descriptors
|
||||
have completed before the dma controller is commanded to read them */
|
||||
smp_wmb();
|
||||
@@ -365,7 +377,7 @@ int mite_buf_change(struct mite_dma_descriptor_ring *ring, struct comedi_async *
|
||||
}
|
||||
|
||||
void mite_prep_dma(struct mite_channel *mite_chan,
|
||||
unsigned int num_device_bits, unsigned int num_memory_bits)
|
||||
unsigned int num_device_bits, unsigned int num_memory_bits)
|
||||
{
|
||||
unsigned int chor, chcr, mcr, dcr, lkcr;
|
||||
struct mite_struct *mite = mite_chan->mite;
|
||||
@@ -378,7 +390,7 @@ void mite_prep_dma(struct mite_channel *mite_chan,
|
||||
|
||||
/* short link chaining mode */
|
||||
chcr = CHCR_SET_DMA_IE | CHCR_LINKSHORT | CHCR_SET_DONE_IE |
|
||||
CHCR_BURSTEN;
|
||||
CHCR_BURSTEN;
|
||||
/*
|
||||
* Link Complete Interrupt: interrupt every time a link
|
||||
* in MITE_RING is completed. This can generate a lot of
|
||||
@@ -413,8 +425,7 @@ void mite_prep_dma(struct mite_channel *mite_chan,
|
||||
mcr |= CR_PSIZE32;
|
||||
break;
|
||||
default:
|
||||
printk
|
||||
("mite: bug! invalid mem bit width for dma transfer\n");
|
||||
printk("mite: bug! invalid mem bit width for dma transfer\n");
|
||||
break;
|
||||
}
|
||||
writel(mcr, mite->mite_io_addr + MITE_MCR(mite_chan->channel));
|
||||
@@ -433,8 +444,7 @@ void mite_prep_dma(struct mite_channel *mite_chan,
|
||||
dcr |= CR_PSIZE32;
|
||||
break;
|
||||
default:
|
||||
printk
|
||||
("mite: bug! invalid dev bit width for dma transfer\n");
|
||||
printk("mite: bug! invalid dev bit width for dma transfer\n");
|
||||
break;
|
||||
}
|
||||
writel(dcr, mite->mite_io_addr + MITE_DCR(mite_chan->channel));
|
||||
@@ -448,7 +458,7 @@ void mite_prep_dma(struct mite_channel *mite_chan,
|
||||
|
||||
/* starting address for link chaining */
|
||||
writel(mite_chan->ring->descriptors_dma_addr,
|
||||
mite->mite_io_addr + MITE_LKAR(mite_chan->channel));
|
||||
mite->mite_io_addr + MITE_LKAR(mite_chan->channel));
|
||||
|
||||
MDPRINTK("exit mite_prep_dma\n");
|
||||
}
|
||||
@@ -459,15 +469,15 @@ u32 mite_device_bytes_transferred(struct mite_channel *mite_chan)
|
||||
return readl(mite->mite_io_addr + MITE_DAR(mite_chan->channel));
|
||||
}
|
||||
|
||||
u32 mite_bytes_in_transit(struct mite_channel *mite_chan)
|
||||
u32 mite_bytes_in_transit(struct mite_channel * mite_chan)
|
||||
{
|
||||
struct mite_struct *mite = mite_chan->mite;
|
||||
return readl(mite->mite_io_addr +
|
||||
MITE_FCR(mite_chan->channel)) & 0x000000FF;
|
||||
MITE_FCR(mite_chan->channel)) & 0x000000FF;
|
||||
}
|
||||
|
||||
/* returns lower bound for number of bytes transferred from device to memory */
|
||||
u32 mite_bytes_written_to_memory_lb(struct mite_channel *mite_chan)
|
||||
u32 mite_bytes_written_to_memory_lb(struct mite_channel * mite_chan)
|
||||
{
|
||||
u32 device_byte_count;
|
||||
|
||||
@@ -476,7 +486,7 @@ u32 mite_bytes_written_to_memory_lb(struct mite_channel *mite_chan)
|
||||
}
|
||||
|
||||
/* returns upper bound for number of bytes transferred from device to memory */
|
||||
u32 mite_bytes_written_to_memory_ub(struct mite_channel *mite_chan)
|
||||
u32 mite_bytes_written_to_memory_ub(struct mite_channel * mite_chan)
|
||||
{
|
||||
u32 in_transit_count;
|
||||
|
||||
@@ -485,7 +495,7 @@ u32 mite_bytes_written_to_memory_ub(struct mite_channel *mite_chan)
|
||||
}
|
||||
|
||||
/* returns lower bound for number of bytes read from memory for transfer to device */
|
||||
u32 mite_bytes_read_from_memory_lb(struct mite_channel *mite_chan)
|
||||
u32 mite_bytes_read_from_memory_lb(struct mite_channel * mite_chan)
|
||||
{
|
||||
u32 device_byte_count;
|
||||
|
||||
@@ -494,7 +504,7 @@ u32 mite_bytes_read_from_memory_lb(struct mite_channel *mite_chan)
|
||||
}
|
||||
|
||||
/* returns upper bound for number of bytes read from memory for transfer to device */
|
||||
u32 mite_bytes_read_from_memory_ub(struct mite_channel *mite_chan)
|
||||
u32 mite_bytes_read_from_memory_ub(struct mite_channel * mite_chan)
|
||||
{
|
||||
u32 in_transit_count;
|
||||
|
||||
@@ -511,7 +521,7 @@ unsigned mite_dma_tcr(struct mite_channel *mite_chan)
|
||||
lkar = readl(mite->mite_io_addr + MITE_LKAR(mite_chan->channel));
|
||||
tcr = readl(mite->mite_io_addr + MITE_TCR(mite_chan->channel));
|
||||
MDPRINTK("mite_dma_tcr ch%i, lkar=0x%08x tcr=%d\n", mite_chan->channel,
|
||||
lkar, tcr);
|
||||
lkar, tcr);
|
||||
|
||||
return tcr;
|
||||
}
|
||||
@@ -526,7 +536,8 @@ void mite_dma_disarm(struct mite_channel *mite_chan)
|
||||
writel(chor, mite->mite_io_addr + MITE_CHOR(mite_chan->channel));
|
||||
}
|
||||
|
||||
int mite_sync_input_dma(struct mite_channel *mite_chan, struct comedi_async * async)
|
||||
int mite_sync_input_dma(struct mite_channel *mite_chan,
|
||||
struct comedi_async *async)
|
||||
{
|
||||
int count;
|
||||
unsigned int nbytes, old_alloc_count;
|
||||
@@ -538,7 +549,7 @@ int mite_sync_input_dma(struct mite_channel *mite_chan, struct comedi_async * as
|
||||
|
||||
nbytes = mite_bytes_written_to_memory_lb(mite_chan);
|
||||
if ((int)(mite_bytes_written_to_memory_ub(mite_chan) -
|
||||
old_alloc_count) > 0) {
|
||||
old_alloc_count) > 0) {
|
||||
printk("mite: DMA overwrite of free area\n");
|
||||
async->events |= COMEDI_CB_OVERFLOW;
|
||||
return -1;
|
||||
@@ -561,24 +572,25 @@ int mite_sync_input_dma(struct mite_channel *mite_chan, struct comedi_async * as
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mite_sync_output_dma(struct mite_channel *mite_chan, struct comedi_async * async)
|
||||
int mite_sync_output_dma(struct mite_channel *mite_chan,
|
||||
struct comedi_async *async)
|
||||
{
|
||||
int count;
|
||||
u32 nbytes_ub, nbytes_lb;
|
||||
unsigned int old_alloc_count;
|
||||
u32 stop_count =
|
||||
async->cmd.stop_arg * cfc_bytes_per_scan(async->subdevice);
|
||||
async->cmd.stop_arg * cfc_bytes_per_scan(async->subdevice);
|
||||
|
||||
old_alloc_count = async->buf_read_alloc_count;
|
||||
/* read alloc as much as we can */
|
||||
comedi_buf_read_alloc(async, async->prealloc_bufsz);
|
||||
nbytes_lb = mite_bytes_read_from_memory_lb(mite_chan);
|
||||
if (async->cmd.stop_src == TRIG_COUNT &&
|
||||
(int)(nbytes_lb - stop_count) > 0)
|
||||
(int)(nbytes_lb - stop_count) > 0)
|
||||
nbytes_lb = stop_count;
|
||||
nbytes_ub = mite_bytes_read_from_memory_ub(mite_chan);
|
||||
if (async->cmd.stop_src == TRIG_COUNT &&
|
||||
(int)(nbytes_ub - stop_count) > 0)
|
||||
(int)(nbytes_ub - stop_count) > 0)
|
||||
nbytes_ub = stop_count;
|
||||
if ((int)(nbytes_ub - old_alloc_count) > 0) {
|
||||
printk("mite: DMA underrun\n");
|
||||
@@ -607,7 +619,7 @@ unsigned mite_get_status(struct mite_channel *mite_chan)
|
||||
if (status & CHSR_DONE) {
|
||||
mite_chan->done = 1;
|
||||
writel(CHOR_CLRDONE,
|
||||
mite->mite_io_addr + MITE_CHOR(mite_chan->channel));
|
||||
mite->mite_io_addr + MITE_CHOR(mite_chan->channel));
|
||||
}
|
||||
mmiowb();
|
||||
spin_unlock_irqrestore(&mite->lock, flags);
|
||||
@@ -703,7 +715,7 @@ static const char *const mite_CHSR_strings[] = {
|
||||
void mite_dump_regs(struct mite_channel *mite_chan)
|
||||
{
|
||||
unsigned long mite_io_addr =
|
||||
(unsigned long)mite_chan->mite->mite_io_addr;
|
||||
(unsigned long)mite_chan->mite->mite_io_addr;
|
||||
unsigned long addr = 0;
|
||||
unsigned long temp = 0;
|
||||
|
||||
@@ -712,37 +724,37 @@ void mite_dump_regs(struct mite_channel *mite_chan)
|
||||
|
||||
addr = mite_io_addr + MITE_CHOR(channel);
|
||||
printk("mite status[CHOR]at 0x%08lx =0x%08lx\n", addr, temp =
|
||||
readl(addr));
|
||||
readl(addr));
|
||||
mite_decode(mite_CHOR_strings, temp);
|
||||
addr = mite_io_addr + MITE_CHCR(channel);
|
||||
printk("mite status[CHCR]at 0x%08lx =0x%08lx\n", addr, temp =
|
||||
readl(addr));
|
||||
readl(addr));
|
||||
mite_decode(mite_CHCR_strings, temp);
|
||||
addr = mite_io_addr + MITE_TCR(channel);
|
||||
printk("mite status[TCR] at 0x%08lx =0x%08x\n", addr, readl(addr));
|
||||
addr = mite_io_addr + MITE_MCR(channel);
|
||||
printk("mite status[MCR] at 0x%08lx =0x%08lx\n", addr, temp =
|
||||
readl(addr));
|
||||
readl(addr));
|
||||
mite_decode(mite_MCR_strings, temp);
|
||||
|
||||
addr = mite_io_addr + MITE_MAR(channel);
|
||||
printk("mite status[MAR] at 0x%08lx =0x%08x\n", addr, readl(addr));
|
||||
addr = mite_io_addr + MITE_DCR(channel);
|
||||
printk("mite status[DCR] at 0x%08lx =0x%08lx\n", addr, temp =
|
||||
readl(addr));
|
||||
readl(addr));
|
||||
mite_decode(mite_DCR_strings, temp);
|
||||
addr = mite_io_addr + MITE_DAR(channel);
|
||||
printk("mite status[DAR] at 0x%08lx =0x%08x\n", addr, readl(addr));
|
||||
addr = mite_io_addr + MITE_LKCR(channel);
|
||||
printk("mite status[LKCR]at 0x%08lx =0x%08lx\n", addr, temp =
|
||||
readl(addr));
|
||||
readl(addr));
|
||||
mite_decode(mite_LKCR_strings, temp);
|
||||
addr = mite_io_addr + MITE_LKAR(channel);
|
||||
printk("mite status[LKAR]at 0x%08lx =0x%08x\n", addr, readl(addr));
|
||||
|
||||
addr = mite_io_addr + MITE_CHSR(channel);
|
||||
printk("mite status[CHSR]at 0x%08lx =0x%08lx\n", addr, temp =
|
||||
readl(addr));
|
||||
readl(addr));
|
||||
mite_decode(mite_CHSR_strings, temp);
|
||||
addr = mite_io_addr + MITE_FCR(channel);
|
||||
printk("mite status[FCR] at 0x%08lx =0x%08x\n\n", addr, readl(addr));
|
||||
|
||||
@@ -80,10 +80,11 @@ struct mite_struct {
|
||||
};
|
||||
|
||||
static inline struct mite_dma_descriptor_ring *mite_alloc_ring(struct
|
||||
mite_struct *mite)
|
||||
mite_struct
|
||||
*mite)
|
||||
{
|
||||
struct mite_dma_descriptor_ring *ring =
|
||||
kmalloc(sizeof(struct mite_dma_descriptor_ring), GFP_KERNEL);
|
||||
kmalloc(sizeof(struct mite_dma_descriptor_ring), GFP_KERNEL);
|
||||
if (ring == NULL)
|
||||
return ring;
|
||||
ring->hw_dev = get_device(&mite->pcidev->dev);
|
||||
@@ -102,9 +103,10 @@ static inline void mite_free_ring(struct mite_dma_descriptor_ring *ring)
|
||||
if (ring) {
|
||||
if (ring->descriptors) {
|
||||
dma_free_coherent(ring->hw_dev,
|
||||
ring->n_links *
|
||||
sizeof(struct mite_dma_descriptor),
|
||||
ring->descriptors, ring->descriptors_dma_addr);
|
||||
ring->n_links *
|
||||
sizeof(struct mite_dma_descriptor),
|
||||
ring->descriptors,
|
||||
ring->descriptors_dma_addr);
|
||||
}
|
||||
put_device(ring->hw_dev);
|
||||
kfree(ring);
|
||||
@@ -117,6 +119,7 @@ static inline unsigned int mite_irq(struct mite_struct *mite)
|
||||
{
|
||||
return mite->pcidev->irq;
|
||||
};
|
||||
|
||||
static inline unsigned int mite_device_id(struct mite_struct *mite)
|
||||
{
|
||||
return mite->pcidev->device;
|
||||
@@ -129,21 +132,29 @@ int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1);
|
||||
void mite_unsetup(struct mite_struct *mite);
|
||||
void mite_list_devices(void);
|
||||
struct mite_channel *mite_request_channel_in_range(struct mite_struct *mite,
|
||||
struct mite_dma_descriptor_ring *ring, unsigned min_channel,
|
||||
unsigned max_channel);
|
||||
struct
|
||||
mite_dma_descriptor_ring
|
||||
*ring, unsigned min_channel,
|
||||
unsigned max_channel);
|
||||
static inline struct mite_channel *mite_request_channel(struct mite_struct
|
||||
*mite, struct mite_dma_descriptor_ring *ring)
|
||||
*mite,
|
||||
struct
|
||||
mite_dma_descriptor_ring
|
||||
*ring)
|
||||
{
|
||||
return mite_request_channel_in_range(mite, ring, 0,
|
||||
mite->num_channels - 1);
|
||||
mite->num_channels - 1);
|
||||
}
|
||||
|
||||
void mite_release_channel(struct mite_channel *mite_chan);
|
||||
|
||||
unsigned mite_dma_tcr(struct mite_channel *mite_chan);
|
||||
void mite_dma_arm(struct mite_channel *mite_chan);
|
||||
void mite_dma_disarm(struct mite_channel *mite_chan);
|
||||
int mite_sync_input_dma(struct mite_channel *mite_chan, struct comedi_async * async);
|
||||
int mite_sync_output_dma(struct mite_channel *mite_chan, struct comedi_async * async);
|
||||
int mite_sync_input_dma(struct mite_channel *mite_chan,
|
||||
struct comedi_async *async);
|
||||
int mite_sync_output_dma(struct mite_channel *mite_chan,
|
||||
struct comedi_async *async);
|
||||
u32 mite_bytes_written_to_memory_lb(struct mite_channel *mite_chan);
|
||||
u32 mite_bytes_written_to_memory_ub(struct mite_channel *mite_chan);
|
||||
u32 mite_bytes_read_from_memory_lb(struct mite_channel *mite_chan);
|
||||
@@ -153,16 +164,16 @@ unsigned mite_get_status(struct mite_channel *mite_chan);
|
||||
int mite_done(struct mite_channel *mite_chan);
|
||||
|
||||
#if 0
|
||||
unsigned long mite_ll_from_kvmem(struct mite_struct *mite, struct comedi_async * async,
|
||||
int len);
|
||||
unsigned long mite_ll_from_kvmem(struct mite_struct *mite,
|
||||
struct comedi_async *async, int len);
|
||||
void mite_setregs(struct mite_struct *mite, unsigned long ll_start, int chan,
|
||||
int dir);
|
||||
int dir);
|
||||
#endif
|
||||
|
||||
void mite_prep_dma(struct mite_channel *mite_chan,
|
||||
unsigned int num_device_bits, unsigned int num_memory_bits);
|
||||
unsigned int num_device_bits, unsigned int num_memory_bits);
|
||||
int mite_buf_change(struct mite_dma_descriptor_ring *ring,
|
||||
struct comedi_async *async);
|
||||
struct comedi_async *async);
|
||||
|
||||
#ifdef DEBUG_MITE
|
||||
void mite_print_chsr(unsigned int chsr);
|
||||
@@ -185,72 +196,88 @@ enum mite_registers {
|
||||
MITE_PCI_CONFIG_OFFSET = 0x300,
|
||||
MITE_CSIGR = 0x460 /* chip signature */
|
||||
};
|
||||
static inline int MITE_CHOR(int channel) /* channel operation */
|
||||
{
|
||||
static inline int MITE_CHOR(int channel)
|
||||
{ /* channel operation */
|
||||
return CHAN_OFFSET(channel) + 0x0;
|
||||
};
|
||||
static inline int MITE_CHCR(int channel) /* channel control */
|
||||
{
|
||||
|
||||
static inline int MITE_CHCR(int channel)
|
||||
{ /* channel control */
|
||||
return CHAN_OFFSET(channel) + 0x4;
|
||||
};
|
||||
static inline int MITE_TCR(int channel) /* transfer count */
|
||||
{
|
||||
|
||||
static inline int MITE_TCR(int channel)
|
||||
{ /* transfer count */
|
||||
return CHAN_OFFSET(channel) + 0x8;
|
||||
};
|
||||
static inline int MITE_MCR(int channel) /* memory configuration */
|
||||
{
|
||||
|
||||
static inline int MITE_MCR(int channel)
|
||||
{ /* memory configuration */
|
||||
return CHAN_OFFSET(channel) + 0xc;
|
||||
};
|
||||
static inline int MITE_MAR(int channel) /* memory address */
|
||||
{
|
||||
|
||||
static inline int MITE_MAR(int channel)
|
||||
{ /* memory address */
|
||||
return CHAN_OFFSET(channel) + 0x10;
|
||||
};
|
||||
static inline int MITE_DCR(int channel) /* device configuration */
|
||||
{
|
||||
|
||||
static inline int MITE_DCR(int channel)
|
||||
{ /* device configuration */
|
||||
return CHAN_OFFSET(channel) + 0x14;
|
||||
};
|
||||
static inline int MITE_DAR(int channel) /* device address */
|
||||
{
|
||||
|
||||
static inline int MITE_DAR(int channel)
|
||||
{ /* device address */
|
||||
return CHAN_OFFSET(channel) + 0x18;
|
||||
};
|
||||
static inline int MITE_LKCR(int channel) /* link configuration */
|
||||
{
|
||||
|
||||
static inline int MITE_LKCR(int channel)
|
||||
{ /* link configuration */
|
||||
return CHAN_OFFSET(channel) + 0x1c;
|
||||
};
|
||||
static inline int MITE_LKAR(int channel) /* link address */
|
||||
{
|
||||
|
||||
static inline int MITE_LKAR(int channel)
|
||||
{ /* link address */
|
||||
return CHAN_OFFSET(channel) + 0x20;
|
||||
};
|
||||
static inline int MITE_LLKAR(int channel) /* see mite section of tnt5002 manual */
|
||||
{
|
||||
|
||||
static inline int MITE_LLKAR(int channel)
|
||||
{ /* see mite section of tnt5002 manual */
|
||||
return CHAN_OFFSET(channel) + 0x24;
|
||||
};
|
||||
static inline int MITE_BAR(int channel) /* base address */
|
||||
{
|
||||
|
||||
static inline int MITE_BAR(int channel)
|
||||
{ /* base address */
|
||||
return CHAN_OFFSET(channel) + 0x28;
|
||||
};
|
||||
static inline int MITE_BCR(int channel) /* base count */
|
||||
{
|
||||
|
||||
static inline int MITE_BCR(int channel)
|
||||
{ /* base count */
|
||||
return CHAN_OFFSET(channel) + 0x2c;
|
||||
};
|
||||
static inline int MITE_SAR(int channel) /* ? address */
|
||||
{
|
||||
|
||||
static inline int MITE_SAR(int channel)
|
||||
{ /* ? address */
|
||||
return CHAN_OFFSET(channel) + 0x30;
|
||||
};
|
||||
static inline int MITE_WSCR(int channel) /* ? */
|
||||
{
|
||||
|
||||
static inline int MITE_WSCR(int channel)
|
||||
{ /* ? */
|
||||
return CHAN_OFFSET(channel) + 0x34;
|
||||
};
|
||||
static inline int MITE_WSER(int channel) /* ? */
|
||||
{
|
||||
|
||||
static inline int MITE_WSER(int channel)
|
||||
{ /* ? */
|
||||
return CHAN_OFFSET(channel) + 0x38;
|
||||
};
|
||||
static inline int MITE_CHSR(int channel) /* channel status */
|
||||
{
|
||||
|
||||
static inline int MITE_CHSR(int channel)
|
||||
{ /* channel status */
|
||||
return CHAN_OFFSET(channel) + 0x3c;
|
||||
};
|
||||
static inline int MITE_FCR(int channel) /* fifo count */
|
||||
{
|
||||
|
||||
static inline int MITE_FCR(int channel)
|
||||
{ /* fifo count */
|
||||
return CHAN_OFFSET(channel) + 0x40;
|
||||
};
|
||||
|
||||
@@ -275,22 +302,27 @@ static inline int mite_csigr_version(u32 csigr_bits)
|
||||
{
|
||||
return csigr_bits & 0xf;
|
||||
};
|
||||
|
||||
static inline int mite_csigr_type(u32 csigr_bits)
|
||||
{ /* original mite = 0, minimite = 1 */
|
||||
return (csigr_bits >> 4) & 0xf;
|
||||
};
|
||||
|
||||
static inline int mite_csigr_mmode(u32 csigr_bits)
|
||||
{ /* mite mode, minimite = 1 */
|
||||
return (csigr_bits >> 8) & 0x3;
|
||||
};
|
||||
|
||||
static inline int mite_csigr_imode(u32 csigr_bits)
|
||||
{ /* cpu port interface mode, pci = 0x3 */
|
||||
return (csigr_bits >> 12) & 0x3;
|
||||
};
|
||||
|
||||
static inline int mite_csigr_dmac(u32 csigr_bits)
|
||||
{ /* number of dma channels */
|
||||
return (csigr_bits >> 16) & 0xf;
|
||||
};
|
||||
|
||||
static inline int mite_csigr_wpdep(u32 csigr_bits)
|
||||
{ /* write post fifo depth */
|
||||
unsigned int wpdep_bits = (csigr_bits >> 20) & 0x7;
|
||||
@@ -299,10 +331,12 @@ static inline int mite_csigr_wpdep(u32 csigr_bits)
|
||||
else
|
||||
return 1 << (wpdep_bits - 1);
|
||||
};
|
||||
|
||||
static inline int mite_csigr_wins(u32 csigr_bits)
|
||||
{
|
||||
return (csigr_bits >> 24) & 0x1f;
|
||||
};
|
||||
|
||||
static inline int mite_csigr_iowins(u32 csigr_bits)
|
||||
{ /* number of io windows */
|
||||
return (csigr_bits >> 29) & 0x7;
|
||||
@@ -366,9 +400,9 @@ enum MITE_CHCR_bits {
|
||||
CHCR_LINKSHORT = (4 << 0),
|
||||
CHCR_LINKLONG = (5 << 0),
|
||||
CHCRPON =
|
||||
(CHCR_CLR_DMA_IE | CHCR_CLR_LINKP_IE | CHCR_CLR_SAR_IE |
|
||||
CHCR_CLR_DONE_IE | CHCR_CLR_MRDY_IE | CHCR_CLR_DRDY_IE |
|
||||
CHCR_CLR_LC_IE | CHCR_CLR_CONT_RB_IE),
|
||||
(CHCR_CLR_DMA_IE | CHCR_CLR_LINKP_IE | CHCR_CLR_SAR_IE |
|
||||
CHCR_CLR_DONE_IE | CHCR_CLR_MRDY_IE | CHCR_CLR_DRDY_IE |
|
||||
CHCR_CLR_LC_IE | CHCR_CLR_CONT_RB_IE),
|
||||
};
|
||||
|
||||
enum ConfigRegister_bits {
|
||||
@@ -390,12 +424,14 @@ static inline int CR_REQS(int source)
|
||||
{
|
||||
return (source & 0x7) << 16;
|
||||
};
|
||||
|
||||
static inline int CR_REQSDRQ(unsigned drq_line)
|
||||
{
|
||||
/* This also works on m-series when
|
||||
using channels (drq_line) 4 or 5. */
|
||||
return CR_REQS((drq_line & 0x3) | 0x4);
|
||||
}
|
||||
|
||||
static inline int CR_RL(unsigned int retry_limit)
|
||||
{
|
||||
int value = 0;
|
||||
@@ -447,7 +483,7 @@ enum CHSR_bits {
|
||||
static inline void mite_dma_reset(struct mite_channel *mite_chan)
|
||||
{
|
||||
writel(CHOR_DMARESET | CHOR_FRESET,
|
||||
mite_chan->mite->mite_io_addr + MITE_CHOR(mite_chan->channel));
|
||||
mite_chan->mite->mite_io_addr + MITE_CHOR(mite_chan->channel));
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -125,28 +125,29 @@ struct skel_private {
|
||||
unsigned long int ulConvertionRate; /* set by mpc624_attach() from driver's parameters */
|
||||
};
|
||||
|
||||
|
||||
#define devpriv ((struct skel_private *)dev->private)
|
||||
/* ---------------------------------------------------------------------------- */
|
||||
static const struct comedi_lrange range_mpc624_bipolar1 = {
|
||||
1,
|
||||
{
|
||||
/* BIP_RANGE(1.01) this is correct, */
|
||||
/* but my MPC-624 actually seems to have a range of 2.02 */
|
||||
BIP_RANGE(2.02)
|
||||
}
|
||||
/* but my MPC-624 actually seems to have a range of 2.02 */
|
||||
BIP_RANGE(2.02)
|
||||
}
|
||||
};
|
||||
|
||||
static const struct comedi_lrange range_mpc624_bipolar10 = {
|
||||
1,
|
||||
{
|
||||
/* BIP_RANGE(10.1) this is correct, */
|
||||
/* but my MPC-624 actually seems to have a range of 20.2 */
|
||||
BIP_RANGE(20.2)
|
||||
}
|
||||
/* but my MPC-624 actually seems to have a range of 20.2 */
|
||||
BIP_RANGE(20.2)
|
||||
}
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------------- */
|
||||
static int mpc624_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int mpc624_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int mpc624_detach(struct comedi_device *dev);
|
||||
/* ---------------------------------------------------------------------------- */
|
||||
static struct comedi_driver driver_mpc624 = {
|
||||
@@ -157,8 +158,9 @@ static struct comedi_driver driver_mpc624 = {
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------------- */
|
||||
static int mpc624_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int mpc624_ai_rinsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
/* ---------------------------------------------------------------------------- */
|
||||
static int mpc624_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
{
|
||||
@@ -222,7 +224,7 @@ static int mpc624_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
break;
|
||||
default:
|
||||
printk
|
||||
("illegal convertion rate setting! Valid numbers are 0..9. Using 9 => 6.875 Hz, ");
|
||||
("illegal convertion rate setting! Valid numbers are 0..9. Using 9 => 6.875 Hz, ");
|
||||
devpriv->ulConvertionRate = MPC624_SPEED_3_52_kHz;
|
||||
}
|
||||
|
||||
@@ -270,8 +272,9 @@ static int mpc624_detach(struct comedi_device *dev)
|
||||
/* Timeout 200ms */
|
||||
#define TIMEOUT 200
|
||||
|
||||
static int mpc624_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int mpc624_ai_rinsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
int n, i;
|
||||
unsigned long int data_in, data_out;
|
||||
@@ -316,16 +319,15 @@ static int mpc624_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s
|
||||
outb(0, dev->iobase + MPC624_ADC);
|
||||
udelay(1);
|
||||
|
||||
if (data_out & (1 << 31)) /* the next bit is a 1 */
|
||||
{
|
||||
if (data_out & (1 << 31)) { /* the next bit is a 1 */
|
||||
/* Set the ADSDI line (send to MPC624) */
|
||||
outb(MPC624_ADSDI, dev->iobase + MPC624_ADC);
|
||||
udelay(1);
|
||||
/* Set the clock high */
|
||||
outb(MPC624_ADSCK | MPC624_ADSDI,
|
||||
dev->iobase + MPC624_ADC);
|
||||
} else /* the next bit is a 0 */
|
||||
{
|
||||
dev->iobase + MPC624_ADC);
|
||||
} else { /* the next bit is a 0 */
|
||||
|
||||
/* Set the ADSDI line (send to MPC624) */
|
||||
outb(0, dev->iobase + MPC624_ADC);
|
||||
udelay(1);
|
||||
@@ -336,8 +338,7 @@ static int mpc624_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s
|
||||
udelay(1);
|
||||
data_in <<= 1;
|
||||
data_in |=
|
||||
(inb(dev->iobase +
|
||||
MPC624_ADC) & MPC624_ADSDO) >> 4;
|
||||
(inb(dev->iobase + MPC624_ADC) & MPC624_ADSDO) >> 4;
|
||||
udelay(1);
|
||||
|
||||
data_out <<= 1;
|
||||
@@ -358,12 +359,11 @@ static int mpc624_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s
|
||||
|
||||
if (data_in & MPC624_EOC_BIT)
|
||||
printk("MPC624: EOC bit is set (data_in=%lu)!",
|
||||
data_in);
|
||||
data_in);
|
||||
if (data_in & MPC624_DMY_BIT)
|
||||
printk("MPC624: DMY bit is set (data_in=%lu)!",
|
||||
data_in);
|
||||
if (data_in & MPC624_SGN_BIT) /* check the sign bit */
|
||||
{ /* The voltage is positive */
|
||||
data_in);
|
||||
if (data_in & MPC624_SGN_BIT) { /* check the sign bit *//* The voltage is positive */
|
||||
data_in &= 0x3FFFFFFF; /* EOC and DMY should be 0, but we will mask them out just to be sure */
|
||||
data[n] = data_in; /* comedi operates on unsigned numbers, so we don't clear the SGN bit */
|
||||
/* SGN bit is still set! It's correct, since we're converting to unsigned. */
|
||||
|
||||
@@ -46,7 +46,8 @@ struct mpc8260cpm_private {
|
||||
|
||||
#define devpriv ((struct mpc8260cpm_private *)dev->private)
|
||||
|
||||
static int mpc8260cpm_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int mpc8260cpm_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int mpc8260cpm_detach(struct comedi_device *dev);
|
||||
static struct comedi_driver driver_mpc8260cpm = {
|
||||
.driver_name = "mpc8260cpm",
|
||||
@@ -57,12 +58,15 @@ static struct comedi_driver driver_mpc8260cpm = {
|
||||
|
||||
COMEDI_INITCLEANUP(driver_mpc8260cpm);
|
||||
|
||||
static int mpc8260cpm_dio_config(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int mpc8260cpm_dio_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int mpc8260cpm_dio_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int mpc8260cpm_dio_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
static int mpc8260cpm_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
static int mpc8260cpm_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it)
|
||||
{
|
||||
struct comedi_subdevice *s;
|
||||
int i;
|
||||
@@ -114,8 +118,9 @@ static unsigned long *cpm_pdat(int port)
|
||||
}
|
||||
}
|
||||
|
||||
static int mpc8260cpm_dio_config(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int mpc8260cpm_dio_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int n;
|
||||
unsigned int d;
|
||||
@@ -157,8 +162,9 @@ static int mpc8260cpm_dio_config(struct comedi_device *dev, struct comedi_subdev
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int mpc8260cpm_dio_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int mpc8260cpm_dio_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int port;
|
||||
unsigned long *p;
|
||||
|
||||
@@ -83,7 +83,8 @@ Devices: [Quanser Consulting] MultiQ-3 (multiq3)
|
||||
|
||||
#define MULTIQ3_TIMEOUT 30
|
||||
|
||||
static int multiq3_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int multiq3_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int multiq3_detach(struct comedi_device *dev);
|
||||
static struct comedi_driver driver_multiq3 = {
|
||||
.driver_name = "multiq3",
|
||||
@@ -99,8 +100,9 @@ struct multiq3_private {
|
||||
};
|
||||
#define devpriv ((struct multiq3_private *)dev->private)
|
||||
|
||||
static int multiq3_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int multiq3_ai_insn_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int i, n;
|
||||
int chan;
|
||||
@@ -108,7 +110,7 @@ static int multiq3_ai_insn_read(struct comedi_device *dev, struct comedi_subdevi
|
||||
|
||||
chan = CR_CHAN(insn->chanspec);
|
||||
outw(MULTIQ3_CONTROL_MUST | MULTIQ3_AD_MUX_EN | (chan << 3),
|
||||
dev->iobase + MULTIQ3_CONTROL);
|
||||
dev->iobase + MULTIQ3_CONTROL);
|
||||
|
||||
for (i = 0; i < MULTIQ3_TIMEOUT; i++) {
|
||||
if (inw(dev->iobase + MULTIQ3_STATUS) & MULTIQ3_STATUS_EOC)
|
||||
@@ -121,7 +123,7 @@ static int multiq3_ai_insn_read(struct comedi_device *dev, struct comedi_subdevi
|
||||
outw(0, dev->iobase + MULTIQ3_AD_CS);
|
||||
for (i = 0; i < MULTIQ3_TIMEOUT; i++) {
|
||||
if (inw(dev->iobase +
|
||||
MULTIQ3_STATUS) & MULTIQ3_STATUS_EOC_I)
|
||||
MULTIQ3_STATUS) & MULTIQ3_STATUS_EOC_I)
|
||||
break;
|
||||
}
|
||||
if (i == MULTIQ3_TIMEOUT)
|
||||
@@ -135,8 +137,9 @@ static int multiq3_ai_insn_read(struct comedi_device *dev, struct comedi_subdevi
|
||||
return n;
|
||||
}
|
||||
|
||||
static int multiq3_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int multiq3_ao_insn_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int i;
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
@@ -148,15 +151,16 @@ static int multiq3_ao_insn_read(struct comedi_device *dev, struct comedi_subdevi
|
||||
return i;
|
||||
}
|
||||
|
||||
static int multiq3_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int multiq3_ao_insn_write(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int i;
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
|
||||
for (i = 0; i < insn->n; i++) {
|
||||
outw(MULTIQ3_CONTROL_MUST | MULTIQ3_DA_LOAD | chan,
|
||||
dev->iobase + MULTIQ3_CONTROL);
|
||||
dev->iobase + MULTIQ3_CONTROL);
|
||||
outw(data[i], dev->iobase + MULTIQ3_DAC_DATA);
|
||||
outw(MULTIQ3_CONTROL_MUST, dev->iobase + MULTIQ3_CONTROL);
|
||||
|
||||
@@ -166,8 +170,9 @@ static int multiq3_ao_insn_write(struct comedi_device *dev, struct comedi_subdev
|
||||
return i;
|
||||
}
|
||||
|
||||
static int multiq3_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int multiq3_di_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
if (insn->n != 2)
|
||||
return -EINVAL;
|
||||
@@ -177,8 +182,9 @@ static int multiq3_di_insn_bits(struct comedi_device *dev, struct comedi_subdevi
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int multiq3_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int multiq3_do_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
if (insn->n != 2)
|
||||
return -EINVAL;
|
||||
@@ -192,8 +198,10 @@ static int multiq3_do_insn_bits(struct comedi_device *dev, struct comedi_subdevi
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int multiq3_encoder_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int multiq3_encoder_insn_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
int n;
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
@@ -218,7 +226,7 @@ static void encoder_reset(struct comedi_device *dev)
|
||||
int chan;
|
||||
for (chan = 0; chan < dev->subdevices[4].n_chan; chan++) {
|
||||
int control =
|
||||
MULTIQ3_CONTROL_MUST | MULTIQ3_AD_MUX_EN | (chan << 3);
|
||||
MULTIQ3_CONTROL_MUST | MULTIQ3_AD_MUX_EN | (chan << 3);
|
||||
outw(control, dev->iobase + MULTIQ3_CONTROL);
|
||||
outb(MULTIQ3_EFLAG_RESET, dev->iobase + MULTIQ3_ENC_CONTROL);
|
||||
outb(MULTIQ3_BP_RESET, dev->iobase + MULTIQ3_ENC_CONTROL);
|
||||
@@ -236,7 +244,8 @@ static void encoder_reset(struct comedi_device *dev)
|
||||
options[2] - number of encoder chips installed
|
||||
*/
|
||||
|
||||
static int multiq3_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
static int multiq3_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it)
|
||||
{
|
||||
int result = 0;
|
||||
unsigned long iobase;
|
||||
|
||||
@@ -76,7 +76,8 @@ Updated: Sat, 25 Jan 2003 13:24:40 -0800
|
||||
#define Rising_Edge_Detection_Enable(x) (0x018+(x))
|
||||
#define Falling_Edge_Detection_Enable(x) (0x020+(x))
|
||||
|
||||
static int ni6527_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int ni6527_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int ni6527_detach(struct comedi_device *dev);
|
||||
static struct comedi_driver driver_ni6527 = {
|
||||
.driver_name = "ni6527",
|
||||
@@ -93,22 +94,23 @@ struct ni6527_board {
|
||||
|
||||
static const struct ni6527_board ni6527_boards[] = {
|
||||
{
|
||||
.dev_id = 0x2b20,
|
||||
.name = "pci-6527",
|
||||
},
|
||||
.dev_id = 0x2b20,
|
||||
.name = "pci-6527",
|
||||
},
|
||||
{
|
||||
.dev_id = 0x2b10,
|
||||
.name = "pxi-6527",
|
||||
},
|
||||
.dev_id = 0x2b10,
|
||||
.name = "pxi-6527",
|
||||
},
|
||||
};
|
||||
|
||||
#define n_ni6527_boards (sizeof(ni6527_boards)/sizeof(ni6527_boards[0]))
|
||||
#define n_ni6527_boards ARRAY_SIZE(ni6527_boards)
|
||||
#define this_board ((const struct ni6527_board *)dev->board_ptr)
|
||||
|
||||
static DEFINE_PCI_DEVICE_TABLE(ni6527_pci_table) = {
|
||||
{PCI_VENDOR_ID_NATINST, 0x2b10, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_NATINST, 0x2b20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{0}
|
||||
{
|
||||
PCI_VENDOR_ID_NATINST, 0x2b10, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_NATINST, 0x2b20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
0}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, ni6527_pci_table);
|
||||
@@ -123,8 +125,9 @@ struct ni6527_private {
|
||||
|
||||
static int ni6527_find_device(struct comedi_device *dev, int bus, int slot);
|
||||
|
||||
static int ni6527_di_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int ni6527_di_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
unsigned int interval;
|
||||
@@ -141,17 +144,14 @@ static int ni6527_di_insn_config(struct comedi_device *dev, struct comedi_subdev
|
||||
|
||||
if (interval != devpriv->filter_interval) {
|
||||
writeb(interval & 0xff,
|
||||
devpriv->mite->daq_io_addr +
|
||||
Filter_Interval(0));
|
||||
devpriv->mite->daq_io_addr + Filter_Interval(0));
|
||||
writeb((interval >> 8) & 0xff,
|
||||
devpriv->mite->daq_io_addr +
|
||||
Filter_Interval(1));
|
||||
devpriv->mite->daq_io_addr + Filter_Interval(1));
|
||||
writeb((interval >> 16) & 0x0f,
|
||||
devpriv->mite->daq_io_addr +
|
||||
Filter_Interval(2));
|
||||
devpriv->mite->daq_io_addr + Filter_Interval(2));
|
||||
|
||||
writeb(ClrInterval,
|
||||
devpriv->mite->daq_io_addr + Clear_Register);
|
||||
devpriv->mite->daq_io_addr + Clear_Register);
|
||||
|
||||
devpriv->filter_interval = interval;
|
||||
}
|
||||
@@ -162,17 +162,18 @@ static int ni6527_di_insn_config(struct comedi_device *dev, struct comedi_subdev
|
||||
}
|
||||
|
||||
writeb(devpriv->filter_enable,
|
||||
devpriv->mite->daq_io_addr + Filter_Enable(0));
|
||||
devpriv->mite->daq_io_addr + Filter_Enable(0));
|
||||
writeb(devpriv->filter_enable >> 8,
|
||||
devpriv->mite->daq_io_addr + Filter_Enable(1));
|
||||
devpriv->mite->daq_io_addr + Filter_Enable(1));
|
||||
writeb(devpriv->filter_enable >> 16,
|
||||
devpriv->mite->daq_io_addr + Filter_Enable(2));
|
||||
devpriv->mite->daq_io_addr + Filter_Enable(2));
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int ni6527_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int ni6527_di_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
if (insn->n != 2)
|
||||
return -EINVAL;
|
||||
@@ -184,8 +185,9 @@ static int ni6527_di_insn_bits(struct comedi_device *dev, struct comedi_subdevic
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int ni6527_do_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int ni6527_do_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
if (insn->n != 2)
|
||||
return -EINVAL;
|
||||
@@ -197,15 +199,15 @@ static int ni6527_do_insn_bits(struct comedi_device *dev, struct comedi_subdevic
|
||||
* but in Comedi, it is represented by 0. */
|
||||
if (data[0] & 0x0000ff) {
|
||||
writeb((s->state ^ 0xff),
|
||||
devpriv->mite->daq_io_addr + Port_Register(3));
|
||||
devpriv->mite->daq_io_addr + Port_Register(3));
|
||||
}
|
||||
if (data[0] & 0x00ff00) {
|
||||
writeb((s->state >> 8) ^ 0xff,
|
||||
devpriv->mite->daq_io_addr + Port_Register(4));
|
||||
devpriv->mite->daq_io_addr + Port_Register(4));
|
||||
}
|
||||
if (data[0] & 0xff0000) {
|
||||
writeb((s->state >> 16) ^ 0xff,
|
||||
devpriv->mite->daq_io_addr + Port_Register(5));
|
||||
devpriv->mite->daq_io_addr + Port_Register(5));
|
||||
}
|
||||
}
|
||||
data[1] = s->state;
|
||||
@@ -226,7 +228,7 @@ static irqreturn_t ni6527_interrupt(int irq, void *d)
|
||||
return IRQ_NONE;
|
||||
|
||||
writeb(ClrEdge | ClrOverflow,
|
||||
devpriv->mite->daq_io_addr + Clear_Register);
|
||||
devpriv->mite->daq_io_addr + Clear_Register);
|
||||
|
||||
comedi_buf_put(s->async, 0);
|
||||
s->async->events |= COMEDI_CB_EOS;
|
||||
@@ -234,8 +236,9 @@ static irqreturn_t ni6527_interrupt(int irq, void *d)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int ni6527_intr_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd)
|
||||
static int ni6527_intr_cmdtest(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd)
|
||||
{
|
||||
int err = 0;
|
||||
int tmp;
|
||||
@@ -310,28 +313,31 @@ static int ni6527_intr_cmdtest(struct comedi_device *dev, struct comedi_subdevic
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ni6527_intr_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
static int ni6527_intr_cmd(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
/* struct comedi_cmd *cmd = &s->async->cmd; */
|
||||
|
||||
writeb(ClrEdge | ClrOverflow,
|
||||
devpriv->mite->daq_io_addr + Clear_Register);
|
||||
devpriv->mite->daq_io_addr + Clear_Register);
|
||||
writeb(FallingEdgeIntEnable | RisingEdgeIntEnable |
|
||||
MasterInterruptEnable | EdgeIntEnable,
|
||||
devpriv->mite->daq_io_addr + Master_Interrupt_Control);
|
||||
MasterInterruptEnable | EdgeIntEnable,
|
||||
devpriv->mite->daq_io_addr + Master_Interrupt_Control);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ni6527_intr_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
static int ni6527_intr_cancel(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
writeb(0x00, devpriv->mite->daq_io_addr + Master_Interrupt_Control);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ni6527_intr_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int ni6527_intr_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
if (insn->n < 1)
|
||||
return -EINVAL;
|
||||
@@ -340,8 +346,9 @@ static int ni6527_intr_insn_bits(struct comedi_device *dev, struct comedi_subdev
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int ni6527_intr_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int ni6527_intr_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
if (insn->n < 1)
|
||||
return -EINVAL;
|
||||
@@ -349,18 +356,18 @@ static int ni6527_intr_insn_config(struct comedi_device *dev, struct comedi_subd
|
||||
return -EINVAL;
|
||||
|
||||
writeb(data[1],
|
||||
devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(0));
|
||||
devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(0));
|
||||
writeb(data[1] >> 8,
|
||||
devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(1));
|
||||
devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(1));
|
||||
writeb(data[1] >> 16,
|
||||
devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(2));
|
||||
devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(2));
|
||||
|
||||
writeb(data[2],
|
||||
devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(0));
|
||||
devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(0));
|
||||
writeb(data[2] >> 8,
|
||||
devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(1));
|
||||
devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(1));
|
||||
writeb(data[2] >> 16,
|
||||
devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(2));
|
||||
devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(2));
|
||||
|
||||
return 2;
|
||||
}
|
||||
@@ -430,7 +437,7 @@ static int ni6527_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
writeb(0x00, devpriv->mite->daq_io_addr + Filter_Enable(2));
|
||||
|
||||
writeb(ClrEdge | ClrOverflow | ClrFilter | ClrInterval,
|
||||
devpriv->mite->daq_io_addr + Clear_Register);
|
||||
devpriv->mite->daq_io_addr + Clear_Register);
|
||||
writeb(0x00, devpriv->mite->daq_io_addr + Master_Interrupt_Control);
|
||||
|
||||
ret = request_irq(mite_irq(devpriv->mite), ni6527_interrupt,
|
||||
@@ -449,7 +456,7 @@ static int ni6527_detach(struct comedi_device *dev)
|
||||
{
|
||||
if (devpriv && devpriv->mite && devpriv->mite->daq_io_addr) {
|
||||
writeb(0x00,
|
||||
devpriv->mite->daq_io_addr + Master_Interrupt_Control);
|
||||
devpriv->mite->daq_io_addr + Master_Interrupt_Control);
|
||||
}
|
||||
|
||||
if (dev->irq) {
|
||||
@@ -473,7 +480,7 @@ static int ni6527_find_device(struct comedi_device *dev, int bus, int slot)
|
||||
continue;
|
||||
if (bus || slot) {
|
||||
if (bus != mite->pcidev->bus->number ||
|
||||
slot != PCI_SLOT(mite->pcidev->devfn))
|
||||
slot != PCI_SLOT(mite->pcidev->devfn))
|
||||
continue;
|
||||
}
|
||||
for (i = 0; i < n_ni6527_boards; i++) {
|
||||
|
||||
@@ -66,18 +66,22 @@ static inline unsigned Port_Data(unsigned port)
|
||||
{
|
||||
return 0x40 + port * ni_65xx_port_offset;
|
||||
}
|
||||
|
||||
static inline unsigned Port_Select(unsigned port)
|
||||
{
|
||||
return 0x41 + port * ni_65xx_port_offset;
|
||||
}
|
||||
|
||||
static inline unsigned Rising_Edge_Detection_Enable(unsigned port)
|
||||
{
|
||||
return 0x42 + port * ni_65xx_port_offset;
|
||||
}
|
||||
|
||||
static inline unsigned Falling_Edge_Detection_Enable(unsigned port)
|
||||
{
|
||||
return 0x43 + port * ni_65xx_port_offset;
|
||||
}
|
||||
|
||||
static inline unsigned Filter_Enable(unsigned port)
|
||||
{
|
||||
return 0x44 + port * ni_65xx_port_offset;
|
||||
@@ -103,7 +107,8 @@ static inline unsigned Filter_Enable(unsigned port)
|
||||
#define OverflowIntEnable 0x02
|
||||
#define EdgeIntEnable 0x01
|
||||
|
||||
static int ni_65xx_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int ni_65xx_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int ni_65xx_detach(struct comedi_device *dev);
|
||||
static struct comedi_driver driver_ni_65xx = {
|
||||
.driver_name = "ni_65xx",
|
||||
@@ -124,161 +129,165 @@ struct ni_65xx_board {
|
||||
|
||||
static const struct ni_65xx_board ni_65xx_boards[] = {
|
||||
{
|
||||
.dev_id = 0x7085,
|
||||
.name = "pci-6509",
|
||||
.num_dio_ports = 12,
|
||||
.invert_outputs = 0},
|
||||
.dev_id = 0x7085,
|
||||
.name = "pci-6509",
|
||||
.num_dio_ports = 12,
|
||||
.invert_outputs = 0},
|
||||
{
|
||||
.dev_id = 0x1710,
|
||||
.name = "pxi-6509",
|
||||
.num_dio_ports = 12,
|
||||
.invert_outputs = 0},
|
||||
.dev_id = 0x1710,
|
||||
.name = "pxi-6509",
|
||||
.num_dio_ports = 12,
|
||||
.invert_outputs = 0},
|
||||
{
|
||||
.dev_id = 0x7124,
|
||||
.name = "pci-6510",
|
||||
.num_di_ports = 4},
|
||||
.dev_id = 0x7124,
|
||||
.name = "pci-6510",
|
||||
.num_di_ports = 4},
|
||||
{
|
||||
.dev_id = 0x70c3,
|
||||
.name = "pci-6511",
|
||||
.num_di_ports = 8},
|
||||
.dev_id = 0x70c3,
|
||||
.name = "pci-6511",
|
||||
.num_di_ports = 8},
|
||||
{
|
||||
.dev_id = 0x70d3,
|
||||
.name = "pxi-6511",
|
||||
.num_di_ports = 8},
|
||||
.dev_id = 0x70d3,
|
||||
.name = "pxi-6511",
|
||||
.num_di_ports = 8},
|
||||
{
|
||||
.dev_id = 0x70cc,
|
||||
.name = "pci-6512",
|
||||
.num_do_ports = 8},
|
||||
.dev_id = 0x70cc,
|
||||
.name = "pci-6512",
|
||||
.num_do_ports = 8},
|
||||
{
|
||||
.dev_id = 0x70d2,
|
||||
.name = "pxi-6512",
|
||||
.num_do_ports = 8},
|
||||
.dev_id = 0x70d2,
|
||||
.name = "pxi-6512",
|
||||
.num_do_ports = 8},
|
||||
{
|
||||
.dev_id = 0x70c8,
|
||||
.name = "pci-6513",
|
||||
.num_do_ports = 8,
|
||||
.invert_outputs = 1},
|
||||
.dev_id = 0x70c8,
|
||||
.name = "pci-6513",
|
||||
.num_do_ports = 8,
|
||||
.invert_outputs = 1},
|
||||
{
|
||||
.dev_id = 0x70d1,
|
||||
.name = "pxi-6513",
|
||||
.num_do_ports = 8,
|
||||
.invert_outputs = 1},
|
||||
.dev_id = 0x70d1,
|
||||
.name = "pxi-6513",
|
||||
.num_do_ports = 8,
|
||||
.invert_outputs = 1},
|
||||
{
|
||||
.dev_id = 0x7088,
|
||||
.name = "pci-6514",
|
||||
.num_di_ports = 4,
|
||||
.num_do_ports = 4,
|
||||
.invert_outputs = 1},
|
||||
.dev_id = 0x7088,
|
||||
.name = "pci-6514",
|
||||
.num_di_ports = 4,
|
||||
.num_do_ports = 4,
|
||||
.invert_outputs = 1},
|
||||
{
|
||||
.dev_id = 0x70CD,
|
||||
.name = "pxi-6514",
|
||||
.num_di_ports = 4,
|
||||
.num_do_ports = 4,
|
||||
.invert_outputs = 1},
|
||||
.dev_id = 0x70CD,
|
||||
.name = "pxi-6514",
|
||||
.num_di_ports = 4,
|
||||
.num_do_ports = 4,
|
||||
.invert_outputs = 1},
|
||||
{
|
||||
.dev_id = 0x7087,
|
||||
.name = "pci-6515",
|
||||
.num_di_ports = 4,
|
||||
.num_do_ports = 4,
|
||||
.invert_outputs = 1},
|
||||
.dev_id = 0x7087,
|
||||
.name = "pci-6515",
|
||||
.num_di_ports = 4,
|
||||
.num_do_ports = 4,
|
||||
.invert_outputs = 1},
|
||||
{
|
||||
.dev_id = 0x70c9,
|
||||
.name = "pxi-6515",
|
||||
.num_di_ports = 4,
|
||||
.num_do_ports = 4,
|
||||
.invert_outputs = 1},
|
||||
.dev_id = 0x70c9,
|
||||
.name = "pxi-6515",
|
||||
.num_di_ports = 4,
|
||||
.num_do_ports = 4,
|
||||
.invert_outputs = 1},
|
||||
{
|
||||
.dev_id = 0x7125,
|
||||
.name = "pci-6516",
|
||||
.num_do_ports = 4,
|
||||
.invert_outputs = 1},
|
||||
.dev_id = 0x7125,
|
||||
.name = "pci-6516",
|
||||
.num_do_ports = 4,
|
||||
.invert_outputs = 1},
|
||||
{
|
||||
.dev_id = 0x7126,
|
||||
.name = "pci-6517",
|
||||
.num_do_ports = 4,
|
||||
.invert_outputs = 1},
|
||||
.dev_id = 0x7126,
|
||||
.name = "pci-6517",
|
||||
.num_do_ports = 4,
|
||||
.invert_outputs = 1},
|
||||
{
|
||||
.dev_id = 0x7127,
|
||||
.name = "pci-6518",
|
||||
.num_di_ports = 2,
|
||||
.num_do_ports = 2,
|
||||
.invert_outputs = 1},
|
||||
.dev_id = 0x7127,
|
||||
.name = "pci-6518",
|
||||
.num_di_ports = 2,
|
||||
.num_do_ports = 2,
|
||||
.invert_outputs = 1},
|
||||
{
|
||||
.dev_id = 0x7128,
|
||||
.name = "pci-6519",
|
||||
.num_di_ports = 2,
|
||||
.num_do_ports = 2,
|
||||
.invert_outputs = 1},
|
||||
.dev_id = 0x7128,
|
||||
.name = "pci-6519",
|
||||
.num_di_ports = 2,
|
||||
.num_do_ports = 2,
|
||||
.invert_outputs = 1},
|
||||
{
|
||||
.dev_id = 0x71c5,
|
||||
.name = "pci-6520",
|
||||
.num_di_ports = 1,
|
||||
.num_do_ports = 1,
|
||||
},
|
||||
.dev_id = 0x71c5,
|
||||
.name = "pci-6520",
|
||||
.num_di_ports = 1,
|
||||
.num_do_ports = 1,
|
||||
},
|
||||
{
|
||||
.dev_id = 0x718b,
|
||||
.name = "pci-6521",
|
||||
.num_di_ports = 1,
|
||||
.num_do_ports = 1,
|
||||
},
|
||||
.dev_id = 0x718b,
|
||||
.name = "pci-6521",
|
||||
.num_di_ports = 1,
|
||||
.num_do_ports = 1,
|
||||
},
|
||||
{
|
||||
.dev_id = 0x718c,
|
||||
.name = "pxi-6521",
|
||||
.num_di_ports = 1,
|
||||
.num_do_ports = 1,
|
||||
},
|
||||
.dev_id = 0x718c,
|
||||
.name = "pxi-6521",
|
||||
.num_di_ports = 1,
|
||||
.num_do_ports = 1,
|
||||
},
|
||||
{
|
||||
.dev_id = 0x70a9,
|
||||
.name = "pci-6528",
|
||||
.num_di_ports = 3,
|
||||
.num_do_ports = 3,
|
||||
},
|
||||
.dev_id = 0x70a9,
|
||||
.name = "pci-6528",
|
||||
.num_di_ports = 3,
|
||||
.num_do_ports = 3,
|
||||
},
|
||||
{
|
||||
.dev_id = 0x7086,
|
||||
.name = "pxi-6528",
|
||||
.num_di_ports = 3,
|
||||
.num_do_ports = 3,
|
||||
},
|
||||
.dev_id = 0x7086,
|
||||
.name = "pxi-6528",
|
||||
.num_di_ports = 3,
|
||||
.num_do_ports = 3,
|
||||
},
|
||||
};
|
||||
|
||||
#define n_ni_65xx_boards (sizeof(ni_65xx_boards)/sizeof(ni_65xx_boards[0]))
|
||||
static inline const struct ni_65xx_board *board(struct comedi_device * dev)
|
||||
#define n_ni_65xx_boards ARRAY_SIZE(ni_65xx_boards)
|
||||
static inline const struct ni_65xx_board *board(struct comedi_device *dev)
|
||||
{
|
||||
return dev->board_ptr;
|
||||
}
|
||||
|
||||
static inline unsigned ni_65xx_port_by_channel(unsigned channel)
|
||||
{
|
||||
return channel / ni_65xx_channels_per_port;
|
||||
}
|
||||
static inline unsigned ni_65xx_total_num_ports(const struct ni_65xx_board *board)
|
||||
|
||||
static inline unsigned ni_65xx_total_num_ports(const struct ni_65xx_board
|
||||
*board)
|
||||
{
|
||||
return board->num_dio_ports + board->num_di_ports + board->num_do_ports;
|
||||
}
|
||||
|
||||
static DEFINE_PCI_DEVICE_TABLE(ni_65xx_pci_table) = {
|
||||
{PCI_VENDOR_ID_NATINST, 0x1710, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_NATINST, 0x7085, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_NATINST, 0x7086, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_NATINST, 0x7087, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_NATINST, 0x7088, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_NATINST, 0x70a9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_NATINST, 0x70c3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_NATINST, 0x70c8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_NATINST, 0x70c9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_NATINST, 0x70cc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_NATINST, 0x70CD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_NATINST, 0x70d1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_NATINST, 0x70d2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_NATINST, 0x70d3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_NATINST, 0x7124, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_NATINST, 0x7125, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_NATINST, 0x7126, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_NATINST, 0x7127, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_NATINST, 0x7128, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_NATINST, 0x718b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_NATINST, 0x718c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_NATINST, 0x71c5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{0}
|
||||
{
|
||||
PCI_VENDOR_ID_NATINST, 0x1710, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_NATINST, 0x7085, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_NATINST, 0x7086, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_NATINST, 0x7087, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_NATINST, 0x7088, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_NATINST, 0x70a9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_NATINST, 0x70c3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_NATINST, 0x70c8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_NATINST, 0x70c9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_NATINST, 0x70cc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_NATINST, 0x70CD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_NATINST, 0x70d1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_NATINST, 0x70d2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_NATINST, 0x70d3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_NATINST, 0x7124, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_NATINST, 0x7125, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_NATINST, 0x7126, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_NATINST, 0x7127, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_NATINST, 0x7128, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_NATINST, 0x718b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_NATINST, 0x718c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_NATINST, 0x71c5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
0}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, ni_65xx_pci_table);
|
||||
@@ -291,7 +300,7 @@ struct ni_65xx_private {
|
||||
unsigned short dio_direction[NI_65XX_MAX_NUM_PORTS];
|
||||
};
|
||||
|
||||
static inline struct ni_65xx_private *private(struct comedi_device * dev)
|
||||
static inline struct ni_65xx_private *private(struct comedi_device *dev)
|
||||
{
|
||||
return dev->private;
|
||||
}
|
||||
@@ -300,14 +309,16 @@ struct ni_65xx_subdevice_private {
|
||||
unsigned base_port;
|
||||
};
|
||||
|
||||
static inline struct ni_65xx_subdevice_private *sprivate(struct comedi_subdevice * subdev)
|
||||
static inline struct ni_65xx_subdevice_private *sprivate(struct comedi_subdevice
|
||||
*subdev)
|
||||
{
|
||||
return subdev->private;
|
||||
}
|
||||
|
||||
static struct ni_65xx_subdevice_private *ni_65xx_alloc_subdevice_private(void)
|
||||
{
|
||||
struct ni_65xx_subdevice_private *subdev_private =
|
||||
kzalloc(sizeof(struct ni_65xx_subdevice_private), GFP_KERNEL);
|
||||
kzalloc(sizeof(struct ni_65xx_subdevice_private), GFP_KERNEL);
|
||||
if (subdev_private == NULL)
|
||||
return NULL;
|
||||
return subdev_private;
|
||||
@@ -315,12 +326,13 @@ static struct ni_65xx_subdevice_private *ni_65xx_alloc_subdevice_private(void)
|
||||
|
||||
static int ni_65xx_find_device(struct comedi_device *dev, int bus, int slot);
|
||||
|
||||
static int ni_65xx_config_filter(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int ni_65xx_config_filter(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
const unsigned chan = CR_CHAN(insn->chanspec);
|
||||
const unsigned port =
|
||||
sprivate(s)->base_port + ni_65xx_port_by_channel(chan);
|
||||
sprivate(s)->base_port + ni_65xx_port_by_channel(chan);
|
||||
|
||||
if (data[0] != INSN_CONFIG_FILTER)
|
||||
return -EINVAL;
|
||||
@@ -328,41 +340,42 @@ static int ni_65xx_config_filter(struct comedi_device *dev, struct comedi_subdev
|
||||
static const unsigned filter_resolution_ns = 200;
|
||||
static const unsigned max_filter_interval = 0xfffff;
|
||||
unsigned interval =
|
||||
(data[1] +
|
||||
(filter_resolution_ns / 2)) / filter_resolution_ns;
|
||||
(data[1] +
|
||||
(filter_resolution_ns / 2)) / filter_resolution_ns;
|
||||
if (interval > max_filter_interval)
|
||||
interval = max_filter_interval;
|
||||
data[1] = interval * filter_resolution_ns;
|
||||
|
||||
if (interval != private(dev)->filter_interval) {
|
||||
writeb(interval,
|
||||
private(dev)->mite->daq_io_addr +
|
||||
Filter_Interval);
|
||||
private(dev)->mite->daq_io_addr +
|
||||
Filter_Interval);
|
||||
private(dev)->filter_interval = interval;
|
||||
}
|
||||
|
||||
private(dev)->filter_enable[port] |=
|
||||
1 << (chan % ni_65xx_channels_per_port);
|
||||
1 << (chan % ni_65xx_channels_per_port);
|
||||
} else {
|
||||
private(dev)->filter_enable[port] &=
|
||||
~(1 << (chan % ni_65xx_channels_per_port));
|
||||
~(1 << (chan % ni_65xx_channels_per_port));
|
||||
}
|
||||
|
||||
writeb(private(dev)->filter_enable[port],
|
||||
private(dev)->mite->daq_io_addr + Filter_Enable(port));
|
||||
private(dev)->mite->daq_io_addr + Filter_Enable(port));
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int ni_65xx_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int ni_65xx_dio_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
unsigned port;
|
||||
|
||||
if (insn->n < 1)
|
||||
return -EINVAL;
|
||||
port = sprivate(s)->base_port +
|
||||
ni_65xx_port_by_channel(CR_CHAN(insn->chanspec));
|
||||
ni_65xx_port_by_channel(CR_CHAN(insn->chanspec));
|
||||
switch (data[0]) {
|
||||
case INSN_CONFIG_FILTER:
|
||||
return ni_65xx_config_filter(dev, s, insn, data);
|
||||
@@ -393,8 +406,9 @@ static int ni_65xx_dio_insn_config(struct comedi_device *dev, struct comedi_subd
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int ni_65xx_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int ni_65xx_dio_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
unsigned base_bitfield_channel;
|
||||
const unsigned max_ports_per_bitfield = 5;
|
||||
@@ -405,8 +419,8 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev, struct comedi_subdev
|
||||
base_bitfield_channel = CR_CHAN(insn->chanspec);
|
||||
for (j = 0; j < max_ports_per_bitfield; ++j) {
|
||||
const unsigned port =
|
||||
sprivate(s)->base_port +
|
||||
ni_65xx_port_by_channel(base_bitfield_channel) + j;
|
||||
sprivate(s)->base_port +
|
||||
ni_65xx_port_by_channel(base_bitfield_channel) + j;
|
||||
unsigned base_port_channel;
|
||||
unsigned port_mask, port_data, port_read_bits;
|
||||
int bitshift;
|
||||
@@ -431,18 +445,17 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev, struct comedi_subdev
|
||||
unsigned bits;
|
||||
private(dev)->output_bits[port] &= ~port_mask;
|
||||
private(dev)->output_bits[port] |=
|
||||
port_data & port_mask;
|
||||
port_data & port_mask;
|
||||
bits = private(dev)->output_bits[port];
|
||||
if (board(dev)->invert_outputs)
|
||||
bits = ~bits;
|
||||
writeb(bits,
|
||||
private(dev)->mite->daq_io_addr +
|
||||
Port_Data(port));
|
||||
private(dev)->mite->daq_io_addr +
|
||||
Port_Data(port));
|
||||
/* printk("wrote 0x%x to port %i\n", bits, port); */
|
||||
}
|
||||
port_read_bits =
|
||||
readb(private(dev)->mite->daq_io_addr +
|
||||
Port_Data(port));
|
||||
readb(private(dev)->mite->daq_io_addr + Port_Data(port));
|
||||
/* printk("read 0x%x from port %i\n", port_read_bits, port); */
|
||||
if (bitshift > 0) {
|
||||
port_read_bits <<= bitshift;
|
||||
@@ -468,7 +481,7 @@ static irqreturn_t ni_65xx_interrupt(int irq, void *d)
|
||||
return IRQ_NONE;
|
||||
|
||||
writeb(ClrEdge | ClrOverflow,
|
||||
private(dev)->mite->daq_io_addr + Clear_Register);
|
||||
private(dev)->mite->daq_io_addr + Clear_Register);
|
||||
|
||||
comedi_buf_put(s->async, 0);
|
||||
s->async->events |= COMEDI_CB_EOS;
|
||||
@@ -476,8 +489,9 @@ static irqreturn_t ni_65xx_interrupt(int irq, void *d)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int ni_65xx_intr_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd)
|
||||
static int ni_65xx_intr_cmdtest(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd)
|
||||
{
|
||||
int err = 0;
|
||||
int tmp;
|
||||
@@ -552,29 +566,32 @@ static int ni_65xx_intr_cmdtest(struct comedi_device *dev, struct comedi_subdevi
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ni_65xx_intr_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
static int ni_65xx_intr_cmd(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
/* struct comedi_cmd *cmd = &s->async->cmd; */
|
||||
|
||||
writeb(ClrEdge | ClrOverflow,
|
||||
private(dev)->mite->daq_io_addr + Clear_Register);
|
||||
private(dev)->mite->daq_io_addr + Clear_Register);
|
||||
writeb(FallingEdgeIntEnable | RisingEdgeIntEnable |
|
||||
MasterInterruptEnable | EdgeIntEnable,
|
||||
private(dev)->mite->daq_io_addr + Master_Interrupt_Control);
|
||||
MasterInterruptEnable | EdgeIntEnable,
|
||||
private(dev)->mite->daq_io_addr + Master_Interrupt_Control);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ni_65xx_intr_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
static int ni_65xx_intr_cancel(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
writeb(0x00,
|
||||
private(dev)->mite->daq_io_addr + Master_Interrupt_Control);
|
||||
private(dev)->mite->daq_io_addr + Master_Interrupt_Control);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ni_65xx_intr_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int ni_65xx_intr_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
if (insn->n < 1)
|
||||
return -EINVAL;
|
||||
@@ -583,8 +600,10 @@ static int ni_65xx_intr_insn_bits(struct comedi_device *dev, struct comedi_subde
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int ni_65xx_intr_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int ni_65xx_intr_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data)
|
||||
{
|
||||
if (insn->n < 1)
|
||||
return -EINVAL;
|
||||
@@ -592,35 +611,36 @@ static int ni_65xx_intr_insn_config(struct comedi_device *dev, struct comedi_sub
|
||||
return -EINVAL;
|
||||
|
||||
writeb(data[1],
|
||||
private(dev)->mite->daq_io_addr +
|
||||
Rising_Edge_Detection_Enable(0));
|
||||
private(dev)->mite->daq_io_addr +
|
||||
Rising_Edge_Detection_Enable(0));
|
||||
writeb(data[1] >> 8,
|
||||
private(dev)->mite->daq_io_addr +
|
||||
Rising_Edge_Detection_Enable(0x10));
|
||||
private(dev)->mite->daq_io_addr +
|
||||
Rising_Edge_Detection_Enable(0x10));
|
||||
writeb(data[1] >> 16,
|
||||
private(dev)->mite->daq_io_addr +
|
||||
Rising_Edge_Detection_Enable(0x20));
|
||||
private(dev)->mite->daq_io_addr +
|
||||
Rising_Edge_Detection_Enable(0x20));
|
||||
writeb(data[1] >> 24,
|
||||
private(dev)->mite->daq_io_addr +
|
||||
Rising_Edge_Detection_Enable(0x30));
|
||||
private(dev)->mite->daq_io_addr +
|
||||
Rising_Edge_Detection_Enable(0x30));
|
||||
|
||||
writeb(data[2],
|
||||
private(dev)->mite->daq_io_addr +
|
||||
Falling_Edge_Detection_Enable(0));
|
||||
private(dev)->mite->daq_io_addr +
|
||||
Falling_Edge_Detection_Enable(0));
|
||||
writeb(data[2] >> 8,
|
||||
private(dev)->mite->daq_io_addr +
|
||||
Falling_Edge_Detection_Enable(0x10));
|
||||
private(dev)->mite->daq_io_addr +
|
||||
Falling_Edge_Detection_Enable(0x10));
|
||||
writeb(data[2] >> 16,
|
||||
private(dev)->mite->daq_io_addr +
|
||||
Falling_Edge_Detection_Enable(0x20));
|
||||
private(dev)->mite->daq_io_addr +
|
||||
Falling_Edge_Detection_Enable(0x20));
|
||||
writeb(data[2] >> 24,
|
||||
private(dev)->mite->daq_io_addr +
|
||||
Falling_Edge_Detection_Enable(0x30));
|
||||
private(dev)->mite->daq_io_addr +
|
||||
Falling_Edge_Detection_Enable(0x30));
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int ni_65xx_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
static int ni_65xx_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it)
|
||||
{
|
||||
struct comedi_subdevice *s;
|
||||
unsigned i;
|
||||
@@ -647,7 +667,7 @@ static int ni_65xx_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
printk(" %s", dev->board_name);
|
||||
|
||||
printk(" ID=0x%02x",
|
||||
readb(private(dev)->mite->daq_io_addr + ID_Register));
|
||||
readb(private(dev)->mite->daq_io_addr + ID_Register));
|
||||
|
||||
ret = alloc_subdevices(dev, 4);
|
||||
if (ret < 0)
|
||||
@@ -658,7 +678,7 @@ static int ni_65xx_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
s->type = COMEDI_SUBD_DI;
|
||||
s->subdev_flags = SDF_READABLE;
|
||||
s->n_chan =
|
||||
board(dev)->num_di_ports * ni_65xx_channels_per_port;
|
||||
board(dev)->num_di_ports * ni_65xx_channels_per_port;
|
||||
s->range_table = &range_digital;
|
||||
s->maxdata = 1;
|
||||
s->insn_config = ni_65xx_dio_insn_config;
|
||||
@@ -676,7 +696,7 @@ static int ni_65xx_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
s->type = COMEDI_SUBD_DO;
|
||||
s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
|
||||
s->n_chan =
|
||||
board(dev)->num_do_ports * ni_65xx_channels_per_port;
|
||||
board(dev)->num_do_ports * ni_65xx_channels_per_port;
|
||||
s->range_table = &range_digital;
|
||||
s->maxdata = 1;
|
||||
s->insn_bits = ni_65xx_dio_insn_bits;
|
||||
@@ -693,7 +713,7 @@ static int ni_65xx_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
s->type = COMEDI_SUBD_DIO;
|
||||
s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
|
||||
s->n_chan =
|
||||
board(dev)->num_dio_ports * ni_65xx_channels_per_port;
|
||||
board(dev)->num_dio_ports * ni_65xx_channels_per_port;
|
||||
s->range_table = &range_digital;
|
||||
s->maxdata = 1;
|
||||
s->insn_config = ni_65xx_dio_insn_config;
|
||||
@@ -705,8 +725,8 @@ static int ni_65xx_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
for (i = 0; i < board(dev)->num_dio_ports; ++i) {
|
||||
/* configure all ports for input */
|
||||
writeb(0x1,
|
||||
private(dev)->mite->daq_io_addr +
|
||||
Port_Select(i));
|
||||
private(dev)->mite->daq_io_addr +
|
||||
Port_Select(i));
|
||||
}
|
||||
} else {
|
||||
s->type = COMEDI_SUBD_UNUSED;
|
||||
@@ -727,18 +747,18 @@ static int ni_65xx_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
|
||||
for (i = 0; i < ni_65xx_total_num_ports(board(dev)); ++i) {
|
||||
writeb(0x00,
|
||||
private(dev)->mite->daq_io_addr + Filter_Enable(i));
|
||||
private(dev)->mite->daq_io_addr + Filter_Enable(i));
|
||||
if (board(dev)->invert_outputs)
|
||||
writeb(0x01,
|
||||
private(dev)->mite->daq_io_addr + Port_Data(i));
|
||||
private(dev)->mite->daq_io_addr + Port_Data(i));
|
||||
else
|
||||
writeb(0x00,
|
||||
private(dev)->mite->daq_io_addr + Port_Data(i));
|
||||
private(dev)->mite->daq_io_addr + Port_Data(i));
|
||||
}
|
||||
writeb(ClrEdge | ClrOverflow,
|
||||
private(dev)->mite->daq_io_addr + Clear_Register);
|
||||
private(dev)->mite->daq_io_addr + Clear_Register);
|
||||
writeb(0x00,
|
||||
private(dev)->mite->daq_io_addr + Master_Interrupt_Control);
|
||||
private(dev)->mite->daq_io_addr + Master_Interrupt_Control);
|
||||
|
||||
/* Set filter interval to 0 (32bit reg) */
|
||||
writeb(0x00000000, private(dev)->mite->daq_io_addr + Filter_Interval);
|
||||
@@ -758,10 +778,10 @@ static int ni_65xx_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
static int ni_65xx_detach(struct comedi_device *dev)
|
||||
{
|
||||
if (private(dev) && private(dev)->mite
|
||||
&& private(dev)->mite->daq_io_addr) {
|
||||
&& private(dev)->mite->daq_io_addr) {
|
||||
writeb(0x00,
|
||||
private(dev)->mite->daq_io_addr +
|
||||
Master_Interrupt_Control);
|
||||
private(dev)->mite->daq_io_addr +
|
||||
Master_Interrupt_Control);
|
||||
}
|
||||
|
||||
if (dev->irq) {
|
||||
@@ -793,7 +813,7 @@ static int ni_65xx_find_device(struct comedi_device *dev, int bus, int slot)
|
||||
continue;
|
||||
if (bus || slot) {
|
||||
if (bus != mite->pcidev->bus->number ||
|
||||
slot != PCI_SLOT(mite->pcidev->devfn))
|
||||
slot != PCI_SLOT(mite->pcidev->devfn))
|
||||
continue;
|
||||
}
|
||||
for (i = 0; i < n_ni_65xx_boards; i++) {
|
||||
|
||||
@@ -201,7 +201,6 @@ struct NI_660xRegisterData {
|
||||
enum ni_660x_register_width size; /* 1 byte, 2 bytes, or 4 bytes */
|
||||
};
|
||||
|
||||
|
||||
static const struct NI_660xRegisterData registerData[NumRegisters] = {
|
||||
{"G0 Interrupt Acknowledge", 0x004, NI_660x_WRITE, DATA_2B},
|
||||
{"G0 Status Register", 0x004, NI_660x_READ, DATA_2B},
|
||||
@@ -316,21 +315,25 @@ static inline unsigned ioconfig_bitshift(unsigned pfi_channel)
|
||||
else
|
||||
return 8;
|
||||
}
|
||||
|
||||
static inline unsigned pfi_output_select_mask(unsigned pfi_channel)
|
||||
{
|
||||
return 0x3 << ioconfig_bitshift(pfi_channel);
|
||||
}
|
||||
|
||||
static inline unsigned pfi_output_select_bits(unsigned pfi_channel,
|
||||
unsigned output_select)
|
||||
unsigned output_select)
|
||||
{
|
||||
return (output_select & 0x3) << ioconfig_bitshift(pfi_channel);
|
||||
}
|
||||
|
||||
static inline unsigned pfi_input_select_mask(unsigned pfi_channel)
|
||||
{
|
||||
return 0x7 << (4 + ioconfig_bitshift(pfi_channel));
|
||||
}
|
||||
|
||||
static inline unsigned pfi_input_select_bits(unsigned pfi_channel,
|
||||
unsigned input_select)
|
||||
unsigned input_select)
|
||||
{
|
||||
return (input_select & 0x7) << (4 + ioconfig_bitshift(pfi_channel));
|
||||
}
|
||||
@@ -341,6 +344,7 @@ static inline unsigned dma_select_mask(unsigned dma_channel)
|
||||
BUG_ON(dma_channel >= MAX_DMA_CHANNEL);
|
||||
return 0x1f << (8 * dma_channel);
|
||||
}
|
||||
|
||||
enum dma_selection {
|
||||
dma_selection_none = 0x1f,
|
||||
};
|
||||
@@ -349,11 +353,13 @@ static inline unsigned dma_selection_counter(unsigned counter_index)
|
||||
BUG_ON(counter_index >= counters_per_chip);
|
||||
return counter_index;
|
||||
}
|
||||
|
||||
static inline unsigned dma_select_bits(unsigned dma_channel, unsigned selection)
|
||||
{
|
||||
BUG_ON(dma_channel >= MAX_DMA_CHANNEL);
|
||||
return (selection << (8 * dma_channel)) & dma_select_mask(dma_channel);
|
||||
}
|
||||
|
||||
static inline unsigned dma_reset_bit(unsigned dma_channel)
|
||||
{
|
||||
BUG_ON(dma_channel >= MAX_DMA_CHANNEL);
|
||||
@@ -388,36 +394,37 @@ struct ni_660x_board {
|
||||
|
||||
static const struct ni_660x_board ni_660x_boards[] = {
|
||||
{
|
||||
.dev_id = 0x2c60,
|
||||
.name = "PCI-6601",
|
||||
.n_chips = 1,
|
||||
},
|
||||
.dev_id = 0x2c60,
|
||||
.name = "PCI-6601",
|
||||
.n_chips = 1,
|
||||
},
|
||||
{
|
||||
.dev_id = 0x1310,
|
||||
.name = "PCI-6602",
|
||||
.n_chips = 2,
|
||||
},
|
||||
.dev_id = 0x1310,
|
||||
.name = "PCI-6602",
|
||||
.n_chips = 2,
|
||||
},
|
||||
{
|
||||
.dev_id = 0x1360,
|
||||
.name = "PXI-6602",
|
||||
.n_chips = 2,
|
||||
},
|
||||
.dev_id = 0x1360,
|
||||
.name = "PXI-6602",
|
||||
.n_chips = 2,
|
||||
},
|
||||
{
|
||||
.dev_id = 0x2cc0,
|
||||
.name = "PXI-6608",
|
||||
.n_chips = 2,
|
||||
},
|
||||
.dev_id = 0x2cc0,
|
||||
.name = "PXI-6608",
|
||||
.n_chips = 2,
|
||||
},
|
||||
};
|
||||
|
||||
#define NI_660X_MAX_NUM_CHIPS 2
|
||||
#define NI_660X_MAX_NUM_COUNTERS (NI_660X_MAX_NUM_CHIPS * counters_per_chip)
|
||||
|
||||
static DEFINE_PCI_DEVICE_TABLE(ni_660x_pci_table) = {
|
||||
{PCI_VENDOR_ID_NATINST, 0x2c60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_NATINST, 0x1310, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_NATINST, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_NATINST, 0x2cc0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{0}
|
||||
{
|
||||
PCI_VENDOR_ID_NATINST, 0x2c60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_NATINST, 0x1310, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_NATINST, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_NATINST, 0x2cc0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
0}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, ni_660x_pci_table);
|
||||
@@ -436,24 +443,26 @@ struct ni_660x_private {
|
||||
unsigned short pfi_output_selects[NUM_PFI_CHANNELS];
|
||||
};
|
||||
|
||||
static inline struct ni_660x_private *private(struct comedi_device * dev)
|
||||
static inline struct ni_660x_private *private(struct comedi_device *dev)
|
||||
{
|
||||
return dev->private;
|
||||
}
|
||||
|
||||
/* initialized in ni_660x_find_device() */
|
||||
static inline const struct ni_660x_board *board(struct comedi_device * dev)
|
||||
static inline const struct ni_660x_board *board(struct comedi_device *dev)
|
||||
{
|
||||
return dev->board_ptr;
|
||||
}
|
||||
|
||||
#define n_ni_660x_boards (sizeof(ni_660x_boards)/sizeof(ni_660x_boards[0]))
|
||||
#define n_ni_660x_boards ARRAY_SIZE(ni_660x_boards)
|
||||
|
||||
static int ni_660x_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int ni_660x_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int ni_660x_detach(struct comedi_device *dev);
|
||||
static void init_tio_chip(struct comedi_device *dev, int chipset);
|
||||
static void ni_660x_select_pfi_output(struct comedi_device *dev, unsigned pfi_channel,
|
||||
unsigned output_select);
|
||||
static void ni_660x_select_pfi_output(struct comedi_device *dev,
|
||||
unsigned pfi_channel,
|
||||
unsigned output_select);
|
||||
|
||||
static struct comedi_driver driver_ni_660x = {
|
||||
.driver_name = "ni_660x",
|
||||
@@ -466,21 +475,28 @@ COMEDI_PCI_INITCLEANUP(driver_ni_660x, ni_660x_pci_table);
|
||||
|
||||
static int ni_660x_find_device(struct comedi_device *dev, int bus, int slot);
|
||||
static int ni_660x_set_pfi_routing(struct comedi_device *dev, unsigned chan,
|
||||
unsigned source);
|
||||
unsigned source);
|
||||
|
||||
/* Possible instructions for a GPCT */
|
||||
static int ni_660x_GPCT_rinsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int ni_660x_GPCT_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
static int ni_660x_GPCT_winsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
/* Possible instructions for Digital IO */
|
||||
static int ni_660x_dio_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
static int ni_660x_dio_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
static inline unsigned ni_660x_num_counters(struct comedi_device *dev)
|
||||
{
|
||||
@@ -697,7 +713,7 @@ static enum NI_660x_Register ni_gpct_to_660x_register(enum ni_gpct_register reg)
|
||||
break;
|
||||
default:
|
||||
printk("%s: unhandled register 0x%x in switch.\n",
|
||||
__func__, reg);
|
||||
__func__, reg);
|
||||
BUG();
|
||||
return 0;
|
||||
break;
|
||||
@@ -706,11 +722,12 @@ static enum NI_660x_Register ni_gpct_to_660x_register(enum ni_gpct_register reg)
|
||||
}
|
||||
|
||||
static inline void ni_660x_write_register(struct comedi_device *dev,
|
||||
unsigned chip_index, unsigned bits, enum NI_660x_Register reg)
|
||||
unsigned chip_index, unsigned bits,
|
||||
enum NI_660x_Register reg)
|
||||
{
|
||||
void *const write_address =
|
||||
private(dev)->mite->daq_io_addr + GPCT_OFFSET[chip_index] +
|
||||
registerData[reg].offset;
|
||||
private(dev)->mite->daq_io_addr + GPCT_OFFSET[chip_index] +
|
||||
registerData[reg].offset;
|
||||
|
||||
switch (registerData[reg].size) {
|
||||
case DATA_2B:
|
||||
@@ -721,18 +738,19 @@ static inline void ni_660x_write_register(struct comedi_device *dev,
|
||||
break;
|
||||
default:
|
||||
printk("%s: %s: bug! unhandled case (reg=0x%x) in switch.\n",
|
||||
__FILE__, __func__, reg);
|
||||
__FILE__, __func__, reg);
|
||||
BUG();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline unsigned ni_660x_read_register(struct comedi_device *dev,
|
||||
unsigned chip_index, enum NI_660x_Register reg)
|
||||
unsigned chip_index,
|
||||
enum NI_660x_Register reg)
|
||||
{
|
||||
void *const read_address =
|
||||
private(dev)->mite->daq_io_addr + GPCT_OFFSET[chip_index] +
|
||||
registerData[reg].offset;
|
||||
private(dev)->mite->daq_io_addr + GPCT_OFFSET[chip_index] +
|
||||
registerData[reg].offset;
|
||||
|
||||
switch (registerData[reg].size) {
|
||||
case DATA_2B:
|
||||
@@ -743,7 +761,7 @@ static inline unsigned ni_660x_read_register(struct comedi_device *dev,
|
||||
break;
|
||||
default:
|
||||
printk("%s: %s: bug! unhandled case (reg=0x%x) in switch.\n",
|
||||
__FILE__, __func__, reg);
|
||||
__FILE__, __func__, reg);
|
||||
BUG();
|
||||
break;
|
||||
}
|
||||
@@ -751,65 +769,72 @@ static inline unsigned ni_660x_read_register(struct comedi_device *dev,
|
||||
}
|
||||
|
||||
static void ni_gpct_write_register(struct ni_gpct *counter, unsigned bits,
|
||||
enum ni_gpct_register reg)
|
||||
enum ni_gpct_register reg)
|
||||
{
|
||||
struct comedi_device *dev = counter->counter_dev->dev;
|
||||
enum NI_660x_Register ni_660x_register = ni_gpct_to_660x_register(reg);
|
||||
ni_660x_write_register(dev, counter->chip_index, bits,
|
||||
ni_660x_register);
|
||||
ni_660x_register);
|
||||
}
|
||||
|
||||
static unsigned ni_gpct_read_register(struct ni_gpct *counter,
|
||||
enum ni_gpct_register reg)
|
||||
enum ni_gpct_register reg)
|
||||
{
|
||||
struct comedi_device *dev = counter->counter_dev->dev;
|
||||
enum NI_660x_Register ni_660x_register = ni_gpct_to_660x_register(reg);
|
||||
return ni_660x_read_register(dev, counter->chip_index,
|
||||
ni_660x_register);
|
||||
ni_660x_register);
|
||||
}
|
||||
|
||||
static inline struct mite_dma_descriptor_ring *mite_ring(struct ni_660x_private * priv,
|
||||
struct ni_gpct *counter)
|
||||
static inline struct mite_dma_descriptor_ring *mite_ring(struct ni_660x_private
|
||||
*priv,
|
||||
struct ni_gpct
|
||||
*counter)
|
||||
{
|
||||
return priv->mite_rings[counter->chip_index][counter->counter_index];
|
||||
}
|
||||
|
||||
static inline void ni_660x_set_dma_channel(struct comedi_device *dev,
|
||||
unsigned mite_channel, struct ni_gpct *counter)
|
||||
unsigned mite_channel,
|
||||
struct ni_gpct *counter)
|
||||
{
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&private(dev)->soft_reg_copy_lock, flags);
|
||||
private(dev)->dma_configuration_soft_copies[counter->chip_index] &=
|
||||
~dma_select_mask(mite_channel);
|
||||
~dma_select_mask(mite_channel);
|
||||
private(dev)->dma_configuration_soft_copies[counter->chip_index] |=
|
||||
dma_select_bits(mite_channel,
|
||||
dma_selection_counter(counter->counter_index));
|
||||
dma_select_bits(mite_channel,
|
||||
dma_selection_counter(counter->counter_index));
|
||||
ni_660x_write_register(dev, counter->chip_index,
|
||||
private(dev)->dma_configuration_soft_copies[counter->
|
||||
chip_index] | dma_reset_bit(mite_channel),
|
||||
DMAConfigRegister);
|
||||
private(dev)->
|
||||
dma_configuration_soft_copies
|
||||
[counter->chip_index] |
|
||||
dma_reset_bit(mite_channel), DMAConfigRegister);
|
||||
mmiowb();
|
||||
spin_unlock_irqrestore(&private(dev)->soft_reg_copy_lock, flags);
|
||||
}
|
||||
|
||||
static inline void ni_660x_unset_dma_channel(struct comedi_device *dev,
|
||||
unsigned mite_channel, struct ni_gpct *counter)
|
||||
unsigned mite_channel,
|
||||
struct ni_gpct *counter)
|
||||
{
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&private(dev)->soft_reg_copy_lock, flags);
|
||||
private(dev)->dma_configuration_soft_copies[counter->chip_index] &=
|
||||
~dma_select_mask(mite_channel);
|
||||
~dma_select_mask(mite_channel);
|
||||
private(dev)->dma_configuration_soft_copies[counter->chip_index] |=
|
||||
dma_select_bits(mite_channel, dma_selection_none);
|
||||
dma_select_bits(mite_channel, dma_selection_none);
|
||||
ni_660x_write_register(dev, counter->chip_index,
|
||||
private(dev)->dma_configuration_soft_copies[counter->
|
||||
chip_index], DMAConfigRegister);
|
||||
private(dev)->
|
||||
dma_configuration_soft_copies
|
||||
[counter->chip_index], DMAConfigRegister);
|
||||
mmiowb();
|
||||
spin_unlock_irqrestore(&private(dev)->soft_reg_copy_lock, flags);
|
||||
}
|
||||
|
||||
static int ni_660x_request_mite_channel(struct comedi_device *dev,
|
||||
struct ni_gpct *counter, enum comedi_io_direction direction)
|
||||
struct ni_gpct *counter,
|
||||
enum comedi_io_direction direction)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct mite_channel *mite_chan;
|
||||
@@ -817,13 +842,12 @@ static int ni_660x_request_mite_channel(struct comedi_device *dev,
|
||||
spin_lock_irqsave(&private(dev)->mite_channel_lock, flags);
|
||||
BUG_ON(counter->mite_chan);
|
||||
mite_chan =
|
||||
mite_request_channel(private(dev)->mite, mite_ring(private(dev),
|
||||
counter));
|
||||
mite_request_channel(private(dev)->mite, mite_ring(private(dev),
|
||||
counter));
|
||||
if (mite_chan == NULL) {
|
||||
spin_unlock_irqrestore(&private(dev)->mite_channel_lock,
|
||||
flags);
|
||||
spin_unlock_irqrestore(&private(dev)->mite_channel_lock, flags);
|
||||
comedi_error(dev,
|
||||
"failed to reserve mite dma channel for counter.");
|
||||
"failed to reserve mite dma channel for counter.");
|
||||
return -EBUSY;
|
||||
}
|
||||
mite_chan->dir = direction;
|
||||
@@ -833,7 +857,8 @@ static int ni_660x_request_mite_channel(struct comedi_device *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ni_660x_release_mite_channel(struct comedi_device *dev, struct ni_gpct *counter)
|
||||
void ni_660x_release_mite_channel(struct comedi_device *dev,
|
||||
struct ni_gpct *counter)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
@@ -858,7 +883,7 @@ static int ni_660x_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
retval = ni_660x_request_mite_channel(dev, counter, COMEDI_INPUT);
|
||||
if (retval) {
|
||||
comedi_error(dev,
|
||||
"no dma channel available for use by counter");
|
||||
"no dma channel available for use by counter");
|
||||
return retval;
|
||||
}
|
||||
ni_tio_acknowledge_and_confirm(counter, NULL, NULL, NULL, NULL);
|
||||
@@ -867,8 +892,8 @@ static int ni_660x_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int ni_660x_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd)
|
||||
static int ni_660x_cmdtest(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_cmd *cmd)
|
||||
{
|
||||
struct ni_gpct *counter = subdev_to_counter(s);
|
||||
|
||||
@@ -893,19 +918,18 @@ static void set_tio_counterswap(struct comedi_device *dev, int chipset)
|
||||
*/
|
||||
if (chipset)
|
||||
ni_660x_write_register(dev, chipset, CounterSwap,
|
||||
ClockConfigRegister);
|
||||
ClockConfigRegister);
|
||||
else
|
||||
ni_660x_write_register(dev, chipset, 0, ClockConfigRegister);
|
||||
}
|
||||
|
||||
static void ni_660x_handle_gpct_interrupt(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s)
|
||||
struct comedi_subdevice *s)
|
||||
{
|
||||
ni_tio_handle_interrupt(subdev_to_counter(s), s);
|
||||
if (s->async->events) {
|
||||
if (s->async->
|
||||
events & (COMEDI_CB_EOA | COMEDI_CB_ERROR |
|
||||
COMEDI_CB_OVERFLOW)) {
|
||||
if (s->async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR |
|
||||
COMEDI_CB_OVERFLOW)) {
|
||||
ni_660x_cancel(dev, s);
|
||||
}
|
||||
comedi_event(dev, s);
|
||||
@@ -943,13 +967,14 @@ static int ni_660x_input_poll(struct comedi_device *dev,
|
||||
return comedi_buf_read_n_available(s->async);
|
||||
}
|
||||
|
||||
static int ni_660x_buf_change(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
unsigned long new_size)
|
||||
static int ni_660x_buf_change(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
unsigned long new_size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = mite_buf_change(mite_ring(private(dev), subdev_to_counter(s)),
|
||||
s->async);
|
||||
s->async);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@@ -982,7 +1007,7 @@ static int ni_660x_alloc_mite_rings(struct comedi_device *dev)
|
||||
for (i = 0; i < board(dev)->n_chips; ++i) {
|
||||
for (j = 0; j < counters_per_chip; ++j) {
|
||||
private(dev)->mite_rings[i][j] =
|
||||
mite_alloc_ring(private(dev)->mite);
|
||||
mite_alloc_ring(private(dev)->mite);
|
||||
if (private(dev)->mite_rings[i][j] == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
@@ -1003,7 +1028,8 @@ static void ni_660x_free_mite_rings(struct comedi_device *dev)
|
||||
}
|
||||
}
|
||||
|
||||
static int ni_660x_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
static int ni_660x_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it)
|
||||
{
|
||||
struct comedi_subdevice *s;
|
||||
int ret;
|
||||
@@ -1056,8 +1082,11 @@ static int ni_660x_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
ni_660x_write_register(dev, 0, 0, STCDIOControl);
|
||||
|
||||
private(dev)->counter_dev = ni_gpct_device_construct(dev,
|
||||
&ni_gpct_write_register, &ni_gpct_read_register,
|
||||
ni_gpct_variant_660x, ni_660x_num_counters(dev));
|
||||
&ni_gpct_write_register,
|
||||
&ni_gpct_read_register,
|
||||
ni_gpct_variant_660x,
|
||||
ni_660x_num_counters
|
||||
(dev));
|
||||
if (private(dev)->counter_dev == NULL)
|
||||
return -ENOMEM;
|
||||
for (i = 0; i < NI_660X_MAX_NUM_COUNTERS; ++i) {
|
||||
@@ -1065,8 +1094,8 @@ static int ni_660x_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
if (i < ni_660x_num_counters(dev)) {
|
||||
s->type = COMEDI_SUBD_COUNTER;
|
||||
s->subdev_flags =
|
||||
SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL |
|
||||
SDF_CMD_READ /* | SDF_CMD_WRITE */ ;
|
||||
SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL |
|
||||
SDF_CMD_READ /* | SDF_CMD_WRITE */ ;
|
||||
s->n_chan = 3;
|
||||
s->maxdata = 0xffffffff;
|
||||
s->insn_read = ni_660x_GPCT_rinsn;
|
||||
@@ -1082,9 +1111,9 @@ static int ni_660x_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
s->private = &private(dev)->counter_dev->counters[i];
|
||||
|
||||
private(dev)->counter_dev->counters[i].chip_index =
|
||||
i / counters_per_chip;
|
||||
i / counters_per_chip;
|
||||
private(dev)->counter_dev->counters[i].counter_index =
|
||||
i % counters_per_chip;
|
||||
i % counters_per_chip;
|
||||
} else {
|
||||
s->type = COMEDI_SUBD_UNUSED;
|
||||
}
|
||||
@@ -1100,7 +1129,7 @@ static int ni_660x_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
ni_660x_set_pfi_routing(dev, i, pfi_output_select_do);
|
||||
else
|
||||
ni_660x_set_pfi_routing(dev, i,
|
||||
pfi_output_select_counter);
|
||||
pfi_output_select_counter);
|
||||
ni_660x_select_pfi_output(dev, i, pfi_output_select_high_Z);
|
||||
}
|
||||
/* to be safe, set counterswap bits on tio chips after all the counter
|
||||
@@ -1119,7 +1148,7 @@ static int ni_660x_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
if (board(dev)->n_chips > 1)
|
||||
global_interrupt_config_bits |= Cascade_Int_Enable_Bit;
|
||||
ni_660x_write_register(dev, 0, global_interrupt_config_bits,
|
||||
GlobalInterruptConfigRegister);
|
||||
GlobalInterruptConfigRegister);
|
||||
printk("attached\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -1145,7 +1174,7 @@ static int ni_660x_detach(struct comedi_device *dev)
|
||||
|
||||
static int
|
||||
ni_660x_GPCT_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
return ni_tio_rinsn(subdev_to_counter(s), insn, data);
|
||||
}
|
||||
@@ -1158,27 +1187,27 @@ static void init_tio_chip(struct comedi_device *dev, int chipset)
|
||||
private(dev)->dma_configuration_soft_copies[chipset] = 0;
|
||||
for (i = 0; i < MAX_DMA_CHANNEL; ++i) {
|
||||
private(dev)->dma_configuration_soft_copies[chipset] |=
|
||||
dma_select_bits(i,
|
||||
dma_selection_none) & dma_select_mask(i);
|
||||
dma_select_bits(i, dma_selection_none) & dma_select_mask(i);
|
||||
}
|
||||
ni_660x_write_register(dev, chipset,
|
||||
private(dev)->dma_configuration_soft_copies[chipset],
|
||||
DMAConfigRegister);
|
||||
for (i = 0; i < NUM_PFI_CHANNELS; ++i)
|
||||
{
|
||||
private(dev)->
|
||||
dma_configuration_soft_copies[chipset],
|
||||
DMAConfigRegister);
|
||||
for (i = 0; i < NUM_PFI_CHANNELS; ++i) {
|
||||
ni_660x_write_register(dev, chipset, 0, IOConfigReg(i));
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
ni_660x_GPCT_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
return ni_tio_insn_config(subdev_to_counter(s), insn, data);
|
||||
}
|
||||
|
||||
static int ni_660x_GPCT_winsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
return ni_tio_winsn(subdev_to_counter(s), insn, data);
|
||||
}
|
||||
@@ -1193,7 +1222,7 @@ static int ni_660x_find_device(struct comedi_device *dev, int bus, int slot)
|
||||
continue;
|
||||
if (bus || slot) {
|
||||
if (bus != mite->pcidev->bus->number ||
|
||||
slot != PCI_SLOT(mite->pcidev->devfn))
|
||||
slot != PCI_SLOT(mite->pcidev->devfn))
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1211,7 +1240,8 @@ static int ni_660x_find_device(struct comedi_device *dev, int bus, int slot)
|
||||
}
|
||||
|
||||
static int ni_660x_dio_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
unsigned base_bitfield_channel = CR_CHAN(insn->chanspec);
|
||||
|
||||
@@ -1225,13 +1255,14 @@ static int ni_660x_dio_insn_bits(struct comedi_device *dev,
|
||||
/* on return, data[1] contains the value of the digital
|
||||
* input and output lines. */
|
||||
data[1] =
|
||||
(ni_660x_read_register(dev, 0,
|
||||
DIO32Input) >> base_bitfield_channel);
|
||||
(ni_660x_read_register(dev, 0,
|
||||
DIO32Input) >> base_bitfield_channel);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static void ni_660x_select_pfi_output(struct comedi_device *dev, unsigned pfi_channel,
|
||||
unsigned output_select)
|
||||
static void ni_660x_select_pfi_output(struct comedi_device *dev,
|
||||
unsigned pfi_channel,
|
||||
unsigned output_select)
|
||||
{
|
||||
static const unsigned counter_4_7_first_pfi = 8;
|
||||
static const unsigned counter_4_7_last_pfi = 23;
|
||||
@@ -1240,33 +1271,41 @@ static void ni_660x_select_pfi_output(struct comedi_device *dev, unsigned pfi_ch
|
||||
unsigned active_bits;
|
||||
unsigned idle_bits;
|
||||
|
||||
if (board (dev)->n_chips > 1) {
|
||||
if (board(dev)->n_chips > 1) {
|
||||
if (output_select == pfi_output_select_counter &&
|
||||
pfi_channel >= counter_4_7_first_pfi &&
|
||||
pfi_channel <= counter_4_7_last_pfi) {
|
||||
pfi_channel >= counter_4_7_first_pfi &&
|
||||
pfi_channel <= counter_4_7_last_pfi) {
|
||||
active_chipset = 1;
|
||||
idle_chipset = 0;
|
||||
}else {
|
||||
} else {
|
||||
active_chipset = 0;
|
||||
idle_chipset = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (idle_chipset != active_chipset) {
|
||||
idle_bits = ni_660x_read_register(dev, idle_chipset, IOConfigReg(pfi_channel));
|
||||
idle_bits =
|
||||
ni_660x_read_register(dev, idle_chipset,
|
||||
IOConfigReg(pfi_channel));
|
||||
idle_bits &= ~pfi_output_select_mask(pfi_channel);
|
||||
idle_bits |= pfi_output_select_bits(pfi_channel, pfi_output_select_high_Z);
|
||||
ni_660x_write_register(dev, idle_chipset, idle_bits, IOConfigReg(pfi_channel));
|
||||
idle_bits |=
|
||||
pfi_output_select_bits(pfi_channel,
|
||||
pfi_output_select_high_Z);
|
||||
ni_660x_write_register(dev, idle_chipset, idle_bits,
|
||||
IOConfigReg(pfi_channel));
|
||||
}
|
||||
|
||||
active_bits = ni_660x_read_register(dev, active_chipset, IOConfigReg(pfi_channel));
|
||||
active_bits =
|
||||
ni_660x_read_register(dev, active_chipset,
|
||||
IOConfigReg(pfi_channel));
|
||||
active_bits &= ~pfi_output_select_mask(pfi_channel);
|
||||
active_bits |= pfi_output_select_bits(pfi_channel, output_select);
|
||||
ni_660x_write_register(dev, active_chipset, active_bits, IOConfigReg(pfi_channel));
|
||||
ni_660x_write_register(dev, active_chipset, active_bits,
|
||||
IOConfigReg(pfi_channel));
|
||||
}
|
||||
|
||||
static int ni_660x_set_pfi_routing(struct comedi_device *dev, unsigned chan,
|
||||
unsigned source)
|
||||
unsigned source)
|
||||
{
|
||||
if (source > num_pfi_output_selects)
|
||||
return -EINVAL;
|
||||
@@ -1284,18 +1323,21 @@ static int ni_660x_set_pfi_routing(struct comedi_device *dev, unsigned chan,
|
||||
private(dev)->pfi_output_selects[chan] = source;
|
||||
if (private(dev)->pfi_direction_bits & (((uint64_t) 1) << chan))
|
||||
ni_660x_select_pfi_output(dev, chan,
|
||||
private(dev)->pfi_output_selects[chan]);
|
||||
private(dev)->
|
||||
pfi_output_selects[chan]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned ni_660x_get_pfi_routing(struct comedi_device *dev, unsigned chan)
|
||||
static unsigned ni_660x_get_pfi_routing(struct comedi_device *dev,
|
||||
unsigned chan)
|
||||
{
|
||||
BUG_ON(chan >= NUM_PFI_CHANNELS);
|
||||
return private(dev)->pfi_output_selects[chan];
|
||||
}
|
||||
|
||||
static void ni660x_config_filter(struct comedi_device *dev, unsigned pfi_channel,
|
||||
enum ni_gpct_filter_select filter)
|
||||
static void ni660x_config_filter(struct comedi_device *dev,
|
||||
unsigned pfi_channel,
|
||||
enum ni_gpct_filter_select filter)
|
||||
{
|
||||
unsigned bits = ni_660x_read_register(dev, 0, IOConfigReg(pfi_channel));
|
||||
bits &= ~pfi_input_select_mask(pfi_channel);
|
||||
@@ -1304,7 +1346,8 @@ static void ni660x_config_filter(struct comedi_device *dev, unsigned pfi_channel
|
||||
}
|
||||
|
||||
static int ni_660x_dio_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
|
||||
@@ -1317,7 +1360,8 @@ static int ni_660x_dio_insn_config(struct comedi_device *dev,
|
||||
case INSN_CONFIG_DIO_OUTPUT:
|
||||
private(dev)->pfi_direction_bits |= ((uint64_t) 1) << chan;
|
||||
ni_660x_select_pfi_output(dev, chan,
|
||||
private(dev)->pfi_output_selects[chan]);
|
||||
private(dev)->
|
||||
pfi_output_selects[chan]);
|
||||
break;
|
||||
case INSN_CONFIG_DIO_INPUT:
|
||||
private(dev)->pfi_direction_bits &= ~(((uint64_t) 1) << chan);
|
||||
@@ -1325,9 +1369,8 @@ static int ni_660x_dio_insn_config(struct comedi_device *dev,
|
||||
break;
|
||||
case INSN_CONFIG_DIO_QUERY:
|
||||
data[1] =
|
||||
(private(dev)->
|
||||
pfi_direction_bits & (((uint64_t) 1) << chan)) ?
|
||||
COMEDI_OUTPUT : COMEDI_INPUT;
|
||||
(private(dev)->pfi_direction_bits &
|
||||
(((uint64_t) 1) << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
|
||||
return 0;
|
||||
case INSN_CONFIG_SET_ROUTING:
|
||||
return ni_660x_set_pfi_routing(dev, chan, data[1]);
|
||||
|
||||
@@ -70,30 +70,32 @@ struct ni_670x_board {
|
||||
|
||||
static const struct ni_670x_board ni_670x_boards[] = {
|
||||
{
|
||||
.dev_id = 0x2c90,
|
||||
.name = "PCI-6703",
|
||||
.ao_chans = 16,
|
||||
.ao_bits = 16,
|
||||
},
|
||||
.dev_id = 0x2c90,
|
||||
.name = "PCI-6703",
|
||||
.ao_chans = 16,
|
||||
.ao_bits = 16,
|
||||
},
|
||||
{
|
||||
.dev_id = 0x1920,
|
||||
.name = "PXI-6704",
|
||||
.ao_chans = 32,
|
||||
.ao_bits = 16,
|
||||
},
|
||||
.dev_id = 0x1920,
|
||||
.name = "PXI-6704",
|
||||
.ao_chans = 32,
|
||||
.ao_bits = 16,
|
||||
},
|
||||
{
|
||||
.dev_id = 0x1290,
|
||||
.name = "PCI-6704",
|
||||
.ao_chans = 32,
|
||||
.ao_bits = 16,
|
||||
},
|
||||
.dev_id = 0x1290,
|
||||
.name = "PCI-6704",
|
||||
.ao_chans = 32,
|
||||
.ao_bits = 16,
|
||||
},
|
||||
};
|
||||
|
||||
static DEFINE_PCI_DEVICE_TABLE(ni_670x_pci_table) = {
|
||||
{PCI_VENDOR_ID_NATINST, 0x2c90, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
{PCI_VENDOR_ID_NATINST, 0x1920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
/* { PCI_VENDOR_ID_NATINST, 0x0000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, */
|
||||
{0}
|
||||
{
|
||||
PCI_VENDOR_ID_NATINST, 0x2c90, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
|
||||
PCI_VENDOR_ID_NATINST, 0x1920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
|
||||
/* { PCI_VENDOR_ID_NATINST, 0x0000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, */
|
||||
{
|
||||
0}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, ni_670x_pci_table);
|
||||
@@ -108,11 +110,11 @@ struct ni_670x_private {
|
||||
unsigned int ao_readback[32];
|
||||
};
|
||||
|
||||
|
||||
#define devpriv ((struct ni_670x_private *)dev->private)
|
||||
#define n_ni_670x_boards (sizeof(ni_670x_boards)/sizeof(ni_670x_boards[0]))
|
||||
#define n_ni_670x_boards ARRAY_SIZE(ni_670x_boards)
|
||||
|
||||
static int ni_670x_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int ni_670x_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int ni_670x_detach(struct comedi_device *dev);
|
||||
|
||||
static struct comedi_driver driver_ni_670x = {
|
||||
@@ -128,16 +130,22 @@ static struct comedi_lrange range_0_20mA = { 1, {RANGE_mA(0, 20)} };
|
||||
|
||||
static int ni_670x_find_device(struct comedi_device *dev, int bus, int slot);
|
||||
|
||||
static int ni_670x_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int ni_670x_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int ni_670x_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int ni_670x_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int ni_670x_ao_winsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int ni_670x_ao_rinsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int ni_670x_dio_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int ni_670x_dio_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn,
|
||||
unsigned int *data);
|
||||
|
||||
static int ni_670x_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
static int ni_670x_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it)
|
||||
{
|
||||
struct comedi_subdevice *s;
|
||||
int ret;
|
||||
@@ -175,7 +183,7 @@ static int ni_670x_attach(struct comedi_device *dev, struct comedi_devconfig *it
|
||||
const struct comedi_lrange **range_table_list;
|
||||
|
||||
range_table_list = kmalloc(sizeof(struct comedi_lrange *) * 32,
|
||||
GFP_KERNEL);
|
||||
GFP_KERNEL);
|
||||
if (!range_table_list)
|
||||
return -ENOMEM;
|
||||
s->range_table_list = range_table_list;
|
||||
@@ -223,8 +231,9 @@ static int ni_670x_detach(struct comedi_device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ni_670x_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int ni_670x_ao_winsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int i;
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
@@ -249,8 +258,9 @@ static int ni_670x_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *
|
||||
return i;
|
||||
}
|
||||
|
||||
static int ni_670x_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int ni_670x_ao_rinsn(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int i;
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
@@ -261,8 +271,9 @@ static int ni_670x_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *
|
||||
return i;
|
||||
}
|
||||
|
||||
static int ni_670x_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int ni_670x_dio_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
if (insn->n != 2)
|
||||
return -EINVAL;
|
||||
@@ -273,7 +284,7 @@ static int ni_670x_dio_insn_bits(struct comedi_device *dev, struct comedi_subdev
|
||||
s->state &= ~data[0];
|
||||
s->state |= data[0] & data[1];
|
||||
writel(s->state,
|
||||
devpriv->mite->daq_io_addr + DIO_PORT0_DATA_OFFSET);
|
||||
devpriv->mite->daq_io_addr + DIO_PORT0_DATA_OFFSET);
|
||||
}
|
||||
|
||||
/* on return, data[1] contains the value of the digital
|
||||
@@ -283,8 +294,9 @@ static int ni_670x_dio_insn_bits(struct comedi_device *dev, struct comedi_subdev
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int ni_670x_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int ni_670x_dio_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
|
||||
@@ -297,8 +309,7 @@ static int ni_670x_dio_insn_config(struct comedi_device *dev, struct comedi_subd
|
||||
break;
|
||||
case INSN_CONFIG_DIO_QUERY:
|
||||
data[1] =
|
||||
(s->
|
||||
io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
|
||||
(s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
|
||||
return insn->n;
|
||||
break;
|
||||
default:
|
||||
@@ -320,7 +331,7 @@ static int ni_670x_find_device(struct comedi_device *dev, int bus, int slot)
|
||||
continue;
|
||||
if (bus || slot) {
|
||||
if (bus != mite->pcidev->bus->number
|
||||
|| slot != PCI_SLOT(mite->pcidev->devfn))
|
||||
|| slot != PCI_SLOT(mite->pcidev->devfn))
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -131,25 +131,25 @@ struct a2150_board {
|
||||
static const struct comedi_lrange range_a2150 = {
|
||||
1,
|
||||
{
|
||||
RANGE(-2.828, 2.828),
|
||||
}
|
||||
RANGE(-2.828, 2.828),
|
||||
}
|
||||
};
|
||||
|
||||
/* enum must match board indices */
|
||||
enum { a2150_c, a2150_s };
|
||||
static const struct a2150_board a2150_boards[] = {
|
||||
{
|
||||
.name = "at-a2150c",
|
||||
.clock = {31250, 22676, 20833, 19531},
|
||||
.num_clocks = 4,
|
||||
.ai_speed = 19531,
|
||||
},
|
||||
.name = "at-a2150c",
|
||||
.clock = {31250, 22676, 20833, 19531},
|
||||
.num_clocks = 4,
|
||||
.ai_speed = 19531,
|
||||
},
|
||||
{
|
||||
.name = "at-a2150s",
|
||||
.clock = {62500, 50000, 41667, 0},
|
||||
.num_clocks = 3,
|
||||
.ai_speed = 41667,
|
||||
},
|
||||
.name = "at-a2150s",
|
||||
.clock = {62500, 50000, 41667, 0},
|
||||
.num_clocks = 3,
|
||||
.ai_speed = 41667,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -167,7 +167,6 @@ struct a2150_private {
|
||||
int config_bits; /* config register bits */
|
||||
};
|
||||
|
||||
|
||||
#define devpriv ((struct a2150_private *)dev->private)
|
||||
|
||||
static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
@@ -182,16 +181,17 @@ static struct comedi_driver driver_a2150 = {
|
||||
};
|
||||
|
||||
static irqreturn_t a2150_interrupt(int irq, void *d);
|
||||
static int a2150_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd);
|
||||
static int a2150_ai_cmdtest(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_cmd *cmd);
|
||||
static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
|
||||
static int a2150_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int a2150_get_timing(struct comedi_device *dev, unsigned int *period,
|
||||
int flags);
|
||||
int flags);
|
||||
static int a2150_probe(struct comedi_device *dev);
|
||||
static int a2150_set_chanlist(struct comedi_device *dev, unsigned int start_channel,
|
||||
unsigned int num_channels);
|
||||
static int a2150_set_chanlist(struct comedi_device *dev,
|
||||
unsigned int start_channel,
|
||||
unsigned int num_channels);
|
||||
/*
|
||||
* A convenient macro that defines init_module() and cleanup_module(),
|
||||
* as necessary.
|
||||
@@ -335,7 +335,7 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
int i;
|
||||
|
||||
printk("comedi%d: %s: io 0x%lx", dev->minor, driver_a2150.driver_name,
|
||||
iobase);
|
||||
iobase);
|
||||
if (irq) {
|
||||
printk(", irq %u", irq);
|
||||
} else {
|
||||
@@ -391,7 +391,7 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
}
|
||||
devpriv->dma = dma;
|
||||
devpriv->dma_buffer =
|
||||
kmalloc(A2150_DMA_BUFFER_SIZE, GFP_KERNEL | GFP_DMA);
|
||||
kmalloc(A2150_DMA_BUFFER_SIZE, GFP_KERNEL | GFP_DMA);
|
||||
if (devpriv->dma_buffer == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -441,7 +441,8 @@ static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
udelay(1000);
|
||||
}
|
||||
if (i == timeout) {
|
||||
printk(" timed out waiting for offset calibration to complete\n");
|
||||
printk
|
||||
(" timed out waiting for offset calibration to complete\n");
|
||||
return -ETIME;
|
||||
}
|
||||
devpriv->config_bits |= ENABLE0_BIT | ENABLE1_BIT;
|
||||
@@ -488,8 +489,8 @@ static int a2150_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int a2150_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_cmd *cmd)
|
||||
static int a2150_ai_cmdtest(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s, struct comedi_cmd *cmd)
|
||||
{
|
||||
int err = 0;
|
||||
int tmp;
|
||||
@@ -589,25 +590,24 @@ static int a2150_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *
|
||||
for (i = 1; i < cmd->chanlist_len; i++) {
|
||||
if (CR_CHAN(cmd->chanlist[i]) != (startChan + i)) {
|
||||
comedi_error(dev,
|
||||
"entries in chanlist must be consecutive channels, counting upwards\n");
|
||||
"entries in chanlist must be consecutive channels, counting upwards\n");
|
||||
err++;
|
||||
}
|
||||
}
|
||||
if (cmd->chanlist_len == 2 && CR_CHAN(cmd->chanlist[0]) == 1) {
|
||||
comedi_error(dev,
|
||||
"length 2 chanlist must be channels 0,1 or channels 2,3");
|
||||
"length 2 chanlist must be channels 0,1 or channels 2,3");
|
||||
err++;
|
||||
}
|
||||
if (cmd->chanlist_len == 3) {
|
||||
comedi_error(dev,
|
||||
"chanlist must have 1,2 or 4 channels");
|
||||
"chanlist must have 1,2 or 4 channels");
|
||||
err++;
|
||||
}
|
||||
if (CR_AREF(cmd->chanlist[0]) != CR_AREF(cmd->chanlist[1]) ||
|
||||
CR_AREF(cmd->chanlist[2]) != CR_AREF(cmd->chanlist[3]))
|
||||
{
|
||||
CR_AREF(cmd->chanlist[2]) != CR_AREF(cmd->chanlist[3])) {
|
||||
comedi_error(dev,
|
||||
"channels 0/1 and 2/3 must have the same analog reference");
|
||||
"channels 0/1 and 2/3 must have the same analog reference");
|
||||
err++;
|
||||
}
|
||||
}
|
||||
@@ -628,12 +628,12 @@ static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
|
||||
if (!dev->irq || !devpriv->dma) {
|
||||
comedi_error(dev,
|
||||
" irq and dma required, cannot do hardware conversions");
|
||||
" irq and dma required, cannot do hardware conversions");
|
||||
return -1;
|
||||
}
|
||||
if (cmd->flags & TRIG_RT) {
|
||||
comedi_error(dev,
|
||||
" dma incompatible with hard real-time interrupt (TRIG_RT), aborting");
|
||||
" dma incompatible with hard real-time interrupt (TRIG_RT), aborting");
|
||||
return -1;
|
||||
}
|
||||
/* clear fifo and reset triggering circuitry */
|
||||
@@ -641,7 +641,7 @@ static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
|
||||
/* setup chanlist */
|
||||
if (a2150_set_chanlist(dev, CR_CHAN(cmd->chanlist[0]),
|
||||
cmd->chanlist_len) < 0)
|
||||
cmd->chanlist_len) < 0)
|
||||
return -1;
|
||||
|
||||
/* setup ac/dc coupling */
|
||||
@@ -673,14 +673,14 @@ static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
/* set size of transfer to fill in 1/3 second */
|
||||
#define ONE_THIRD_SECOND 333333333
|
||||
devpriv->dma_transfer_size =
|
||||
sizeof(devpriv->dma_buffer[0]) * cmd->chanlist_len *
|
||||
ONE_THIRD_SECOND / cmd->scan_begin_arg;
|
||||
sizeof(devpriv->dma_buffer[0]) * cmd->chanlist_len *
|
||||
ONE_THIRD_SECOND / cmd->scan_begin_arg;
|
||||
if (devpriv->dma_transfer_size > A2150_DMA_BUFFER_SIZE)
|
||||
devpriv->dma_transfer_size = A2150_DMA_BUFFER_SIZE;
|
||||
if (devpriv->dma_transfer_size < sizeof(devpriv->dma_buffer[0]))
|
||||
devpriv->dma_transfer_size = sizeof(devpriv->dma_buffer[0]);
|
||||
devpriv->dma_transfer_size -=
|
||||
devpriv->dma_transfer_size % sizeof(devpriv->dma_buffer[0]);
|
||||
devpriv->dma_transfer_size % sizeof(devpriv->dma_buffer[0]);
|
||||
set_dma_count(devpriv->dma, devpriv->dma_transfer_size);
|
||||
enable_dma(devpriv->dma);
|
||||
release_dma_lock(lock_flags);
|
||||
@@ -700,8 +700,8 @@ static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
trigger_bits = 0;
|
||||
/* decide if we need to wait 72 periods for valid data */
|
||||
if (cmd->start_src == TRIG_NOW &&
|
||||
(old_config_bits & CLOCK_MASK) !=
|
||||
(devpriv->config_bits & CLOCK_MASK)) {
|
||||
(old_config_bits & CLOCK_MASK) !=
|
||||
(devpriv->config_bits & CLOCK_MASK)) {
|
||||
/* set trigger source to delay trigger */
|
||||
trigger_bits |= DELAY_TRIGGER_BITS;
|
||||
} else {
|
||||
@@ -730,7 +730,7 @@ static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
}
|
||||
|
||||
static int a2150_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
unsigned int i, n;
|
||||
static const int timeout = 100000;
|
||||
@@ -804,7 +804,7 @@ static int a2150_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
/* sets bits in devpriv->clock_bits to nearest approximation of requested period,
|
||||
* adjusts requested period to actual timing. */
|
||||
static int a2150_get_timing(struct comedi_device *dev, unsigned int *period,
|
||||
int flags)
|
||||
int flags)
|
||||
{
|
||||
int lub, glb, temp;
|
||||
int lub_divisor_shift, lub_index, glb_divisor_shift, glb_index;
|
||||
@@ -866,19 +866,20 @@ static int a2150_get_timing(struct comedi_device *dev, unsigned int *period,
|
||||
devpriv->config_bits &= ~CLOCK_MASK;
|
||||
if (*period == lub) {
|
||||
devpriv->config_bits |=
|
||||
CLOCK_SELECT_BITS(lub_index) |
|
||||
CLOCK_DIVISOR_BITS(lub_divisor_shift);
|
||||
CLOCK_SELECT_BITS(lub_index) |
|
||||
CLOCK_DIVISOR_BITS(lub_divisor_shift);
|
||||
} else {
|
||||
devpriv->config_bits |=
|
||||
CLOCK_SELECT_BITS(glb_index) |
|
||||
CLOCK_DIVISOR_BITS(glb_divisor_shift);
|
||||
CLOCK_SELECT_BITS(glb_index) |
|
||||
CLOCK_DIVISOR_BITS(glb_divisor_shift);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int a2150_set_chanlist(struct comedi_device *dev, unsigned int start_channel,
|
||||
unsigned int num_channels)
|
||||
static int a2150_set_chanlist(struct comedi_device *dev,
|
||||
unsigned int start_channel,
|
||||
unsigned int num_channels)
|
||||
{
|
||||
if (start_channel + num_channels > 4)
|
||||
return -1;
|
||||
|
||||
@@ -158,13 +158,13 @@ struct atao_board {
|
||||
|
||||
static const struct atao_board atao_boards[] = {
|
||||
{
|
||||
.name = "ai-ao-6",
|
||||
.n_ao_chans = 6,
|
||||
},
|
||||
.name = "ai-ao-6",
|
||||
.n_ao_chans = 6,
|
||||
},
|
||||
{
|
||||
.name = "ai-ao-10",
|
||||
.n_ao_chans = 10,
|
||||
},
|
||||
.name = "ai-ao-10",
|
||||
.n_ao_chans = 10,
|
||||
},
|
||||
};
|
||||
|
||||
#define thisboard ((struct atao_board *)dev->board_ptr)
|
||||
@@ -198,17 +198,21 @@ COMEDI_INITCLEANUP(driver_atao);
|
||||
static void atao_reset(struct comedi_device *dev);
|
||||
|
||||
static int atao_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int atao_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int atao_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int atao_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int atao_calib_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int atao_calib_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int atao_dio_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int atao_dio_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int atao_calib_insn_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
static int atao_calib_insn_write(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data);
|
||||
|
||||
static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
{
|
||||
@@ -324,7 +328,7 @@ static void atao_reset(struct comedi_device *dev)
|
||||
}
|
||||
|
||||
static int atao_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int i;
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
@@ -348,7 +352,7 @@ static int atao_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
}
|
||||
|
||||
static int atao_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int i;
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
@@ -359,8 +363,9 @@ static int atao_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
return i;
|
||||
}
|
||||
|
||||
static int atao_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int atao_dio_insn_bits(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
if (insn->n != 2)
|
||||
return -EINVAL;
|
||||
@@ -376,8 +381,9 @@ static int atao_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int atao_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int atao_dio_insn_config(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int chan = CR_CHAN(insn->chanspec);
|
||||
unsigned int mask, bit;
|
||||
@@ -401,8 +407,7 @@ static int atao_dio_insn_config(struct comedi_device *dev, struct comedi_subdevi
|
||||
break;
|
||||
case INSN_CONFIG_DIO_QUERY:
|
||||
data[1] =
|
||||
(s->
|
||||
io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
|
||||
(s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
|
||||
return insn->n;
|
||||
break;
|
||||
default:
|
||||
@@ -421,8 +426,9 @@ static int atao_dio_insn_config(struct comedi_device *dev, struct comedi_subdevi
|
||||
* DACs. It is not explicitly stated in the manual how to access
|
||||
* the caldacs, but we can guess.
|
||||
*/
|
||||
static int atao_calib_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int atao_calib_insn_read(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < insn->n; i++) {
|
||||
@@ -431,8 +437,9 @@ static int atao_calib_insn_read(struct comedi_device *dev, struct comedi_subdevi
|
||||
return insn->n;
|
||||
}
|
||||
|
||||
static int atao_calib_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
static int atao_calib_insn_write(struct comedi_device *dev,
|
||||
struct comedi_subdevice *s,
|
||||
struct comedi_insn *insn, unsigned int *data)
|
||||
{
|
||||
unsigned int bitstring, bit;
|
||||
unsigned int chan = CR_CHAN(insn->chanspec);
|
||||
@@ -441,13 +448,13 @@ static int atao_calib_insn_write(struct comedi_device *dev, struct comedi_subdev
|
||||
|
||||
for (bit = 1 << (11 - 1); bit; bit >>= 1) {
|
||||
outw(devpriv->cfg2 | ((bit & bitstring) ? SDATA : 0),
|
||||
dev->iobase + ATAO_CFG2);
|
||||
dev->iobase + ATAO_CFG2);
|
||||
outw(devpriv->cfg2 | SCLK | ((bit & bitstring) ? SDATA : 0),
|
||||
dev->iobase + ATAO_CFG2);
|
||||
dev->iobase + ATAO_CFG2);
|
||||
}
|
||||
/* strobe the appropriate caldac */
|
||||
outw(devpriv->cfg2 | (((chan >> 3) + 1) << 14),
|
||||
dev->iobase + ATAO_CFG2);
|
||||
dev->iobase + ATAO_CFG2);
|
||||
outw(devpriv->cfg2, dev->iobase + ATAO_CFG2);
|
||||
|
||||
return insn->n;
|
||||
|
||||
@@ -117,159 +117,159 @@ are not supported.
|
||||
|
||||
static const struct ni_board_struct ni_boards[] = {
|
||||
{.device_id = 44,
|
||||
.isapnp_id = 0x0000,/* XXX unknown */
|
||||
.name = "at-mio-16e-1",
|
||||
.n_adchan = 16,
|
||||
.adbits = 12,
|
||||
.ai_fifo_depth = 8192,
|
||||
.alwaysdither = 0,
|
||||
.gainlkup = ai_gain_16,
|
||||
.ai_speed = 800,
|
||||
.n_aochan = 2,
|
||||
.aobits = 12,
|
||||
.ao_fifo_depth = 2048,
|
||||
.ao_range_table = &range_ni_E_ao_ext,
|
||||
.ao_unipolar = 1,
|
||||
.ao_speed = 1000,
|
||||
.has_8255 = 0,
|
||||
.num_p0_dio_channels = 8,
|
||||
.caldac = {mb88341},
|
||||
},
|
||||
.isapnp_id = 0x0000, /* XXX unknown */
|
||||
.name = "at-mio-16e-1",
|
||||
.n_adchan = 16,
|
||||
.adbits = 12,
|
||||
.ai_fifo_depth = 8192,
|
||||
.alwaysdither = 0,
|
||||
.gainlkup = ai_gain_16,
|
||||
.ai_speed = 800,
|
||||
.n_aochan = 2,
|
||||
.aobits = 12,
|
||||
.ao_fifo_depth = 2048,
|
||||
.ao_range_table = &range_ni_E_ao_ext,
|
||||
.ao_unipolar = 1,
|
||||
.ao_speed = 1000,
|
||||
.has_8255 = 0,
|
||||
.num_p0_dio_channels = 8,
|
||||
.caldac = {mb88341},
|
||||
},
|
||||
{.device_id = 25,
|
||||
.isapnp_id = 0x1900,
|
||||
.name = "at-mio-16e-2",
|
||||
.n_adchan = 16,
|
||||
.adbits = 12,
|
||||
.ai_fifo_depth = 2048,
|
||||
.alwaysdither = 0,
|
||||
.gainlkup = ai_gain_16,
|
||||
.ai_speed = 2000,
|
||||
.n_aochan = 2,
|
||||
.aobits = 12,
|
||||
.ao_fifo_depth = 2048,
|
||||
.ao_range_table = &range_ni_E_ao_ext,
|
||||
.ao_unipolar = 1,
|
||||
.ao_speed = 1000,
|
||||
.has_8255 = 0,
|
||||
.num_p0_dio_channels = 8,
|
||||
.caldac = {mb88341},
|
||||
},
|
||||
.isapnp_id = 0x1900,
|
||||
.name = "at-mio-16e-2",
|
||||
.n_adchan = 16,
|
||||
.adbits = 12,
|
||||
.ai_fifo_depth = 2048,
|
||||
.alwaysdither = 0,
|
||||
.gainlkup = ai_gain_16,
|
||||
.ai_speed = 2000,
|
||||
.n_aochan = 2,
|
||||
.aobits = 12,
|
||||
.ao_fifo_depth = 2048,
|
||||
.ao_range_table = &range_ni_E_ao_ext,
|
||||
.ao_unipolar = 1,
|
||||
.ao_speed = 1000,
|
||||
.has_8255 = 0,
|
||||
.num_p0_dio_channels = 8,
|
||||
.caldac = {mb88341},
|
||||
},
|
||||
{.device_id = 36,
|
||||
.isapnp_id = 0x2400,
|
||||
.name = "at-mio-16e-10",
|
||||
.n_adchan = 16,
|
||||
.adbits = 12,
|
||||
.ai_fifo_depth = 512,
|
||||
.alwaysdither = 0,
|
||||
.gainlkup = ai_gain_16,
|
||||
.ai_speed = 10000,
|
||||
.n_aochan = 2,
|
||||
.aobits = 12,
|
||||
.ao_fifo_depth = 0,
|
||||
.ao_range_table = &range_ni_E_ao_ext,
|
||||
.ao_unipolar = 1,
|
||||
.ao_speed = 10000,
|
||||
.num_p0_dio_channels = 8,
|
||||
.caldac = {ad8804_debug},
|
||||
.has_8255 = 0,
|
||||
},
|
||||
.isapnp_id = 0x2400,
|
||||
.name = "at-mio-16e-10",
|
||||
.n_adchan = 16,
|
||||
.adbits = 12,
|
||||
.ai_fifo_depth = 512,
|
||||
.alwaysdither = 0,
|
||||
.gainlkup = ai_gain_16,
|
||||
.ai_speed = 10000,
|
||||
.n_aochan = 2,
|
||||
.aobits = 12,
|
||||
.ao_fifo_depth = 0,
|
||||
.ao_range_table = &range_ni_E_ao_ext,
|
||||
.ao_unipolar = 1,
|
||||
.ao_speed = 10000,
|
||||
.num_p0_dio_channels = 8,
|
||||
.caldac = {ad8804_debug},
|
||||
.has_8255 = 0,
|
||||
},
|
||||
{.device_id = 37,
|
||||
.isapnp_id = 0x2500,
|
||||
.name = "at-mio-16de-10",
|
||||
.n_adchan = 16,
|
||||
.adbits = 12,
|
||||
.ai_fifo_depth = 512,
|
||||
.alwaysdither = 0,
|
||||
.gainlkup = ai_gain_16,
|
||||
.ai_speed = 10000,
|
||||
.n_aochan = 2,
|
||||
.aobits = 12,
|
||||
.ao_fifo_depth = 0,
|
||||
.ao_range_table = &range_ni_E_ao_ext,
|
||||
.ao_unipolar = 1,
|
||||
.ao_speed = 10000,
|
||||
.num_p0_dio_channels = 8,
|
||||
.caldac = {ad8804_debug},
|
||||
.has_8255 = 1,
|
||||
},
|
||||
.isapnp_id = 0x2500,
|
||||
.name = "at-mio-16de-10",
|
||||
.n_adchan = 16,
|
||||
.adbits = 12,
|
||||
.ai_fifo_depth = 512,
|
||||
.alwaysdither = 0,
|
||||
.gainlkup = ai_gain_16,
|
||||
.ai_speed = 10000,
|
||||
.n_aochan = 2,
|
||||
.aobits = 12,
|
||||
.ao_fifo_depth = 0,
|
||||
.ao_range_table = &range_ni_E_ao_ext,
|
||||
.ao_unipolar = 1,
|
||||
.ao_speed = 10000,
|
||||
.num_p0_dio_channels = 8,
|
||||
.caldac = {ad8804_debug},
|
||||
.has_8255 = 1,
|
||||
},
|
||||
{.device_id = 38,
|
||||
.isapnp_id = 0x2600,
|
||||
.name = "at-mio-64e-3",
|
||||
.n_adchan = 64,
|
||||
.adbits = 12,
|
||||
.ai_fifo_depth = 2048,
|
||||
.alwaysdither = 0,
|
||||
.gainlkup = ai_gain_16,
|
||||
.ai_speed = 2000,
|
||||
.n_aochan = 2,
|
||||
.aobits = 12,
|
||||
.ao_fifo_depth = 2048,
|
||||
.ao_range_table = &range_ni_E_ao_ext,
|
||||
.ao_unipolar = 1,
|
||||
.ao_speed = 1000,
|
||||
.has_8255 = 0,
|
||||
.num_p0_dio_channels = 8,
|
||||
.caldac = {ad8804_debug},
|
||||
},
|
||||
.isapnp_id = 0x2600,
|
||||
.name = "at-mio-64e-3",
|
||||
.n_adchan = 64,
|
||||
.adbits = 12,
|
||||
.ai_fifo_depth = 2048,
|
||||
.alwaysdither = 0,
|
||||
.gainlkup = ai_gain_16,
|
||||
.ai_speed = 2000,
|
||||
.n_aochan = 2,
|
||||
.aobits = 12,
|
||||
.ao_fifo_depth = 2048,
|
||||
.ao_range_table = &range_ni_E_ao_ext,
|
||||
.ao_unipolar = 1,
|
||||
.ao_speed = 1000,
|
||||
.has_8255 = 0,
|
||||
.num_p0_dio_channels = 8,
|
||||
.caldac = {ad8804_debug},
|
||||
},
|
||||
{.device_id = 39,
|
||||
.isapnp_id = 0x2700,
|
||||
.name = "at-mio-16xe-50",
|
||||
.n_adchan = 16,
|
||||
.adbits = 16,
|
||||
.ai_fifo_depth = 512,
|
||||
.alwaysdither = 1,
|
||||
.gainlkup = ai_gain_8,
|
||||
.ai_speed = 50000,
|
||||
.n_aochan = 2,
|
||||
.aobits = 12,
|
||||
.ao_fifo_depth = 0,
|
||||
.ao_range_table = &range_bipolar10,
|
||||
.ao_unipolar = 0,
|
||||
.ao_speed = 50000,
|
||||
.num_p0_dio_channels = 8,
|
||||
.caldac = {dac8800, dac8043},
|
||||
.has_8255 = 0,
|
||||
},
|
||||
.isapnp_id = 0x2700,
|
||||
.name = "at-mio-16xe-50",
|
||||
.n_adchan = 16,
|
||||
.adbits = 16,
|
||||
.ai_fifo_depth = 512,
|
||||
.alwaysdither = 1,
|
||||
.gainlkup = ai_gain_8,
|
||||
.ai_speed = 50000,
|
||||
.n_aochan = 2,
|
||||
.aobits = 12,
|
||||
.ao_fifo_depth = 0,
|
||||
.ao_range_table = &range_bipolar10,
|
||||
.ao_unipolar = 0,
|
||||
.ao_speed = 50000,
|
||||
.num_p0_dio_channels = 8,
|
||||
.caldac = {dac8800, dac8043},
|
||||
.has_8255 = 0,
|
||||
},
|
||||
{.device_id = 50,
|
||||
.isapnp_id = 0x0000,/* XXX unknown */
|
||||
.name = "at-mio-16xe-10",
|
||||
.n_adchan = 16,
|
||||
.adbits = 16,
|
||||
.ai_fifo_depth = 512,
|
||||
.alwaysdither = 1,
|
||||
.gainlkup = ai_gain_14,
|
||||
.ai_speed = 10000,
|
||||
.n_aochan = 2,
|
||||
.aobits = 16,
|
||||
.ao_fifo_depth = 2048,
|
||||
.ao_range_table = &range_ni_E_ao_ext,
|
||||
.ao_unipolar = 1,
|
||||
.ao_speed = 1000,
|
||||
.num_p0_dio_channels = 8,
|
||||
.caldac = {dac8800, dac8043, ad8522},
|
||||
.has_8255 = 0,
|
||||
},
|
||||
.isapnp_id = 0x0000, /* XXX unknown */
|
||||
.name = "at-mio-16xe-10",
|
||||
.n_adchan = 16,
|
||||
.adbits = 16,
|
||||
.ai_fifo_depth = 512,
|
||||
.alwaysdither = 1,
|
||||
.gainlkup = ai_gain_14,
|
||||
.ai_speed = 10000,
|
||||
.n_aochan = 2,
|
||||
.aobits = 16,
|
||||
.ao_fifo_depth = 2048,
|
||||
.ao_range_table = &range_ni_E_ao_ext,
|
||||
.ao_unipolar = 1,
|
||||
.ao_speed = 1000,
|
||||
.num_p0_dio_channels = 8,
|
||||
.caldac = {dac8800, dac8043, ad8522},
|
||||
.has_8255 = 0,
|
||||
},
|
||||
{.device_id = 51,
|
||||
.isapnp_id = 0x0000,/* XXX unknown */
|
||||
.name = "at-ai-16xe-10",
|
||||
.n_adchan = 16,
|
||||
.adbits = 16,
|
||||
.ai_fifo_depth = 512,
|
||||
.alwaysdither = 1, /* unknown */
|
||||
.gainlkup = ai_gain_14,
|
||||
.ai_speed = 10000,
|
||||
.n_aochan = 0,
|
||||
.aobits = 0,
|
||||
.ao_fifo_depth = 0,
|
||||
.ao_unipolar = 0,
|
||||
.num_p0_dio_channels = 8,
|
||||
.caldac = {dac8800, dac8043, ad8522},
|
||||
.has_8255 = 0,
|
||||
}
|
||||
.isapnp_id = 0x0000, /* XXX unknown */
|
||||
.name = "at-ai-16xe-10",
|
||||
.n_adchan = 16,
|
||||
.adbits = 16,
|
||||
.ai_fifo_depth = 512,
|
||||
.alwaysdither = 1, /* unknown */
|
||||
.gainlkup = ai_gain_14,
|
||||
.ai_speed = 10000,
|
||||
.n_aochan = 0,
|
||||
.aobits = 0,
|
||||
.ao_fifo_depth = 0,
|
||||
.ao_unipolar = 0,
|
||||
.num_p0_dio_channels = 8,
|
||||
.caldac = {dac8800, dac8043, ad8522},
|
||||
.has_8255 = 0,
|
||||
}
|
||||
};
|
||||
|
||||
static const int ni_irqpin[] =
|
||||
{ -1, -1, -1, 0, 1, 2, -1, 3, -1, -1, 4, 5, 6, -1, -1, 7 };
|
||||
{ -1, -1, -1, 0, 1, 2, -1, 3, -1, -1, 4, 5, 6, -1, -1, 7 };
|
||||
|
||||
#define interrupt_pin(a) (ni_irqpin[(a)])
|
||||
|
||||
@@ -279,8 +279,7 @@ static const int ni_irqpin[] =
|
||||
|
||||
struct ni_private {
|
||||
struct pnp_dev *isapnp_dev;
|
||||
NI_PRIVATE_COMMON
|
||||
};
|
||||
NI_PRIVATE_COMMON};
|
||||
#define devpriv ((struct ni_private *)dev->private)
|
||||
|
||||
/* How we access registers */
|
||||
@@ -330,17 +329,18 @@ static uint16_t ni_atmio_win_in(struct comedi_device *dev, int addr)
|
||||
}
|
||||
|
||||
static struct pnp_device_id device_ids[] = {
|
||||
{.id = "NIC1900", .driver_data = 0},
|
||||
{.id = "NIC2400", .driver_data = 0},
|
||||
{.id = "NIC2500", .driver_data = 0},
|
||||
{.id = "NIC2600", .driver_data = 0},
|
||||
{.id = "NIC2700", .driver_data = 0},
|
||||
{.id = "NIC1900",.driver_data = 0},
|
||||
{.id = "NIC2400",.driver_data = 0},
|
||||
{.id = "NIC2500",.driver_data = 0},
|
||||
{.id = "NIC2600",.driver_data = 0},
|
||||
{.id = "NIC2700",.driver_data = 0},
|
||||
{.id = ""}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(pnp, device_ids);
|
||||
|
||||
static int ni_atmio_attach(struct comedi_device *dev, struct comedi_devconfig *it);
|
||||
static int ni_atmio_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it);
|
||||
static int ni_atmio_detach(struct comedi_device *dev);
|
||||
static struct comedi_driver driver_atmio = {
|
||||
.driver_name = "ni_atmio",
|
||||
@@ -378,14 +378,17 @@ static int ni_isapnp_find_board(struct pnp_dev **dev)
|
||||
|
||||
for (i = 0; i < n_ni_boards; i++) {
|
||||
isapnp_dev = pnp_find_dev(NULL,
|
||||
ISAPNP_VENDOR('N', 'I', 'C'),
|
||||
ISAPNP_FUNCTION(ni_boards[i].isapnp_id), NULL);
|
||||
ISAPNP_VENDOR('N', 'I', 'C'),
|
||||
ISAPNP_FUNCTION(ni_boards[i].
|
||||
isapnp_id), NULL);
|
||||
|
||||
if (isapnp_dev == NULL || isapnp_dev->card == NULL)
|
||||
continue;
|
||||
|
||||
if (pnp_device_attach(isapnp_dev) < 0) {
|
||||
printk("ni_atmio: %s found but already active, skipping.\n", ni_boards[i].name);
|
||||
printk
|
||||
("ni_atmio: %s found but already active, skipping.\n",
|
||||
ni_boards[i].name);
|
||||
continue;
|
||||
}
|
||||
if (pnp_activate_dev(isapnp_dev) < 0) {
|
||||
@@ -393,7 +396,7 @@ static int ni_isapnp_find_board(struct pnp_dev **dev)
|
||||
return -EAGAIN;
|
||||
}
|
||||
if (!pnp_port_valid(isapnp_dev, 0)
|
||||
|| !pnp_irq_valid(isapnp_dev, 0)) {
|
||||
|| !pnp_irq_valid(isapnp_dev, 0)) {
|
||||
pnp_device_detach(isapnp_dev);
|
||||
printk("ni_atmio: pnp invalid port or irq, aborting\n");
|
||||
return -ENOMEM;
|
||||
@@ -406,7 +409,8 @@ static int ni_isapnp_find_board(struct pnp_dev **dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ni_atmio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
|
||||
static int ni_atmio_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it)
|
||||
{
|
||||
struct pnp_dev *isapnp_dev;
|
||||
int ret;
|
||||
@@ -455,7 +459,7 @@ static int ni_atmio_attach(struct comedi_device *dev, struct comedi_devconfig *i
|
||||
printk(" board fingerprint:");
|
||||
for (i = 0; i < 16; i += 2) {
|
||||
printk(" %04x %02x", inw(dev->iobase + i),
|
||||
inb(dev->iobase + i + 1));
|
||||
inb(dev->iobase + i + 1));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user