2
comedi/drivers/jr3_pci.c
3
hardware driver for JR3/PCI force sensor board
5
COMEDI - Linux Control and Measurement Device Interface
6
Copyright (C) 2007 Anders Blomdell <anders.blomdell@control.lth.se>
8
This program is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 2 of the License, or
11
(at your option) any later version.
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
GNU General Public License for more details.
18
You should have received a copy of the GNU General Public License
19
along with this program; if not, write to the Free Software
20
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25
Description: JR3/PCI force sensor board
26
Author: Anders Blomdell <anders.blomdell@control.lth.se>
28
Devices: [JR3] PCI force sensor board (jr3_pci)
30
The DSP on the board requires initialization code, which can
31
be loaded by placing it in /lib/firmware/comedi.
32
The initialization code should be somewhere on the media you got
33
with your card. One version is available from http://www.comedi.org
34
in the comedi_nonfree_firmware tarball.
36
Configuration options:
37
[0] - PCI bus number - if bus number and slot number are 0,
38
then driver search for first unused card
43
#include "../comedidev.h"
45
#include <linux/delay.h>
46
#include <linux/ctype.h>
47
#include <linux/firmware.h>
48
#include <linux/jiffies.h>
49
#include <linux/slab.h>
50
#include <linux/timer.h>
51
#include <linux/kernel.h>
52
#include "comedi_pci.h"
55
#define PCI_VENDOR_ID_JR3 0x1762
56
#define PCI_DEVICE_ID_JR3_1_CHANNEL 0x3111
57
#define PCI_DEVICE_ID_JR3_1_CHANNEL_NEW 0x1111
58
#define PCI_DEVICE_ID_JR3_2_CHANNEL 0x3112
59
#define PCI_DEVICE_ID_JR3_3_CHANNEL 0x3113
60
#define PCI_DEVICE_ID_JR3_4_CHANNEL 0x3114
62
static int jr3_pci_attach(struct comedi_device *dev,
63
struct comedi_devconfig *it);
64
static int jr3_pci_detach(struct comedi_device *dev);
66
static struct comedi_driver driver_jr3_pci = {
67
.driver_name = "jr3_pci",
68
.module = THIS_MODULE,
69
.attach = jr3_pci_attach,
70
.detach = jr3_pci_detach,
73
static DEFINE_PCI_DEVICE_TABLE(jr3_pci_pci_table) = {
75
PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_1_CHANNEL,
76
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
77
PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_1_CHANNEL_NEW,
78
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
79
PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_2_CHANNEL,
80
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
81
PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_3_CHANNEL,
82
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
83
PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_4_CHANNEL,
84
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
88
MODULE_DEVICE_TABLE(pci, jr3_pci_pci_table);
90
struct jr3_pci_dev_private {
92
struct pci_dev *pci_dev;
94
volatile struct jr3_t *iobase;
96
struct timer_list timer;
105
struct jr3_pci_subdev_private {
106
volatile struct jr3_channel *channel;
107
unsigned long next_time_min;
108
unsigned long next_time_max;
109
enum { state_jr3_poll,
110
state_jr3_init_wait_for_offset,
111
state_jr3_init_transform_complete,
112
state_jr3_init_set_full_scale_complete,
113
state_jr3_init_use_offset_complete,
121
struct comedi_krange range;
123
const struct comedi_lrange *range_table_list[8 * 7 + 2];
124
unsigned int maxdata_list[8 * 7 + 2];
129
/* Hotplug firmware loading stuff */
130
static int comedi_load_firmware(struct comedi_device *dev, char *name,
131
int (*cb)(struct comedi_device *dev,
132
const u8 *data, size_t size))
135
const struct firmware *fw;
137
static const char *prefix = "comedi/";
138
struct jr3_pci_dev_private *devpriv = dev->private;
140
firmware_path = kmalloc(strlen(prefix) + strlen(name) + 1, GFP_KERNEL);
141
if (!firmware_path) {
144
firmware_path[0] = '\0';
145
strcat(firmware_path, prefix);
146
strcat(firmware_path, name);
147
result = request_firmware(&fw, firmware_path,
148
&devpriv->pci_dev->dev);
153
result = cb(dev, fw->data, fw->size);
154
release_firmware(fw);
156
kfree(firmware_path);
161
static struct poll_delay_t poll_delay_min_max(int min, int max)
163
struct poll_delay_t result;
170
static int is_complete(volatile struct jr3_channel *channel)
172
return get_s16(&channel->command_word0) == 0;
182
static void set_transforms(volatile struct jr3_channel *channel,
183
struct transform_t transf, short num)
187
num &= 0x000f; /* Make sure that 0 <= num <= 15 */
188
for (i = 0; i < 8; i++) {
190
set_u16(&channel->transforms[num].link[i].link_type,
191
transf.link[i].link_type);
193
set_s16(&channel->transforms[num].link[i].link_amount,
194
transf.link[i].link_amount);
196
if (transf.link[i].link_type == end_x_form)
201
static void use_transform(volatile struct jr3_channel *channel,
204
set_s16(&channel->command_word0, 0x0500 + (transf_num & 0x000f));
207
static void use_offset(volatile struct jr3_channel *channel, short offset_num)
209
set_s16(&channel->command_word0, 0x0600 + (offset_num & 0x000f));
212
static void set_offset(volatile struct jr3_channel *channel)
214
set_s16(&channel->command_word0, 0x0700);
226
static void set_full_scales(volatile struct jr3_channel *channel,
227
struct six_axis_t full_scale)
229
printk("%d %d %d %d %d %d\n",
232
full_scale.fz, full_scale.mx, full_scale.my, full_scale.mz);
233
set_s16(&channel->full_scale.fx, full_scale.fx);
234
set_s16(&channel->full_scale.fy, full_scale.fy);
235
set_s16(&channel->full_scale.fz, full_scale.fz);
236
set_s16(&channel->full_scale.mx, full_scale.mx);
237
set_s16(&channel->full_scale.my, full_scale.my);
238
set_s16(&channel->full_scale.mz, full_scale.mz);
239
set_s16(&channel->command_word0, 0x0a00);
242
static struct six_axis_t get_min_full_scales(volatile struct jr3_channel
245
struct six_axis_t result;
246
result.fx = get_s16(&channel->min_full_scale.fx);
247
result.fy = get_s16(&channel->min_full_scale.fy);
248
result.fz = get_s16(&channel->min_full_scale.fz);
249
result.mx = get_s16(&channel->min_full_scale.mx);
250
result.my = get_s16(&channel->min_full_scale.my);
251
result.mz = get_s16(&channel->min_full_scale.mz);
255
static struct six_axis_t get_max_full_scales(volatile struct jr3_channel
258
struct six_axis_t result;
259
result.fx = get_s16(&channel->max_full_scale.fx);
260
result.fy = get_s16(&channel->max_full_scale.fy);
261
result.fz = get_s16(&channel->max_full_scale.fz);
262
result.mx = get_s16(&channel->max_full_scale.mx);
263
result.my = get_s16(&channel->max_full_scale.my);
264
result.mz = get_s16(&channel->max_full_scale.mz);
268
static int jr3_pci_ai_insn_read(struct comedi_device *dev,
269
struct comedi_subdevice *s,
270
struct comedi_insn *insn, unsigned int *data)
273
struct jr3_pci_subdev_private *p;
277
channel = CR_CHAN(insn->chanspec);
278
if (p == NULL || channel > 57) {
284
if (p->state != state_jr3_done ||
285
(get_u16(&p->channel->errors) & (watch_dog | watch_dog2 |
287
/* No sensor or sensor changed */
288
if (p->state == state_jr3_done) {
289
/* Restart polling */
290
p->state = state_jr3_poll;
294
for (i = 0; i < insn->n; i++) {
299
filter = channel / 8;
300
if (p->state != state_jr3_done) {
354
data[i] = F + 0x4000;
356
} else if (channel == 56) {
357
if (p->state != state_jr3_done) {
361
get_u16(&p->channel->model_no);
363
} else if (channel == 57) {
364
if (p->state != state_jr3_done) {
368
get_u16(&p->channel->serial_no);
376
static int jr3_pci_open(struct comedi_device *dev)
379
struct jr3_pci_dev_private *devpriv = dev->private;
381
printk("jr3_pci_open\n");
382
for (i = 0; i < devpriv->n_channels; i++) {
383
struct jr3_pci_subdev_private *p;
385
p = dev->subdevices[i].private;
387
printk("serial: %p %d (%d)\n", p, p->serial_no,
394
int read_idm_word(const u8 * data, size_t size, int *pos, unsigned int *val)
397
if (pos != 0 && val != 0) {
398
/* Skip over non hex */
399
for (; *pos < size && !isxdigit(data[*pos]); (*pos)++) {
403
for (; *pos < size; (*pos)++) {
405
value = hex_to_bin(data[*pos]);
408
*val = (*val << 4) + value;
416
static int jr3_download_firmware(struct comedi_device *dev, const u8 * data,
420
* IDM file format is:
421
* { count, address, data <count> } *
424
int result, more, pos, OK;
431
unsigned int count, addr;
433
more = more && read_idm_word(data, size, &pos, &count);
434
if (more && count == 0xffff) {
438
more = more && read_idm_word(data, size, &pos, &addr);
439
while (more && count > 0) {
441
more = more && read_idm_word(data, size, &pos, &dummy);
450
struct jr3_pci_dev_private *p = dev->private;
452
for (i = 0; i < p->n_channels; i++) {
453
struct jr3_pci_subdev_private *sp;
455
sp = dev->subdevices[i].private;
459
unsigned int count, addr;
461
&& read_idm_word(data, size, &pos, &count);
462
if (more && count == 0xffff)
465
&& read_idm_word(data, size, &pos, &addr);
466
printk("Loading#%d %4.4x bytes at %4.4x\n", i,
468
while (more && count > 0) {
470
/* 16 bit data, never seen in real life!! */
474
&& read_idm_word(data,
478
/* printk("jr3_data, not tested\n"); */
479
/* jr3[addr + 0x20000 * pnum] = data1; */
481
/* Download 24 bit program */
482
unsigned int data1, data2;
485
&& read_idm_word(data,
489
&& read_idm_word(data, size,
515
static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice *s)
517
struct poll_delay_t result = poll_delay_min_max(1000, 2000);
518
struct jr3_pci_subdev_private *p = s->private;
522
volatile struct jr3_channel *channel = p->channel;
523
int errors = get_u16(&channel->errors);
525
if (errors != p->errors) {
526
printk("Errors: %x -> %x\n", p->errors, errors);
529
if (errors & (watch_dog | watch_dog2 | sensor_change)) {
530
/* Sensor communication lost, force poll mode */
531
p->state = state_jr3_poll;
535
case state_jr3_poll:{
536
u16 model_no = get_u16(&channel->model_no);
537
u16 serial_no = get_u16(&channel->serial_no);
538
if ((errors & (watch_dog | watch_dog2)) ||
539
model_no == 0 || serial_no == 0) {
541
* Still no sensor, keep on polling. Since it takes up to 10 seconds
542
* for offsets to stabilize, polling each second should suffice.
544
result = poll_delay_min_max(1000, 2000);
548
state_jr3_init_wait_for_offset;
549
result = poll_delay_min_max(1000, 2000);
553
case state_jr3_init_wait_for_offset:{
555
if (p->retries < 10) {
556
/* Wait for offeset to stabilize (< 10 s according to manual) */
557
result = poll_delay_min_max(1000, 2000);
559
struct transform_t transf;
562
get_u16(&channel->model_no);
564
get_u16(&channel->serial_no);
567
("Setting transform for channel %d\n",
569
printk("Sensor Model = %i\n",
571
printk("Sensor Serial = %i\n",
574
/* Transformation all zeros */
575
for (i = 0; i < ARRAY_SIZE(transf.link); i++) {
576
transf.link[i].link_type =
578
transf.link[i].link_amount = 0;
581
set_transforms(channel, transf, 0);
582
use_transform(channel, 0);
584
state_jr3_init_transform_complete;
585
result = poll_delay_min_max(20, 100); /* Allow 20 ms for completion */
588
case state_jr3_init_transform_complete:{
589
if (!is_complete(channel)) {
591
("state_jr3_init_transform_complete complete = %d\n",
592
is_complete(channel));
593
result = poll_delay_min_max(20, 100);
596
struct six_axis_t min_full_scale;
597
struct six_axis_t max_full_scale;
600
get_min_full_scales(channel);
601
printk("Obtained Min. Full Scales:\n");
602
printk("%i ", (min_full_scale).fx);
603
printk("%i ", (min_full_scale).fy);
604
printk("%i ", (min_full_scale).fz);
605
printk("%i ", (min_full_scale).mx);
606
printk("%i ", (min_full_scale).my);
607
printk("%i ", (min_full_scale).mz);
611
get_max_full_scales(channel);
612
printk("Obtained Max. Full Scales:\n");
613
printk("%i ", (max_full_scale).fx);
614
printk("%i ", (max_full_scale).fy);
615
printk("%i ", (max_full_scale).fz);
616
printk("%i ", (max_full_scale).mx);
617
printk("%i ", (max_full_scale).my);
618
printk("%i ", (max_full_scale).mz);
621
set_full_scales(channel,
625
state_jr3_init_set_full_scale_complete;
626
result = poll_delay_min_max(20, 100); /* Allow 20 ms for completion */
630
case state_jr3_init_set_full_scale_complete:{
631
if (!is_complete(channel)) {
633
("state_jr3_init_set_full_scale_complete complete = %d\n",
634
is_complete(channel));
635
result = poll_delay_min_max(20, 100);
637
volatile struct force_array *full_scale;
639
/* Use ranges in kN or we will overflow arount 2000N! */
640
full_scale = &channel->full_scale;
641
p->range[0].range.min =
642
-get_s16(&full_scale->fx) * 1000;
643
p->range[0].range.max =
644
get_s16(&full_scale->fx) * 1000;
645
p->range[1].range.min =
646
-get_s16(&full_scale->fy) * 1000;
647
p->range[1].range.max =
648
get_s16(&full_scale->fy) * 1000;
649
p->range[2].range.min =
650
-get_s16(&full_scale->fz) * 1000;
651
p->range[2].range.max =
652
get_s16(&full_scale->fz) * 1000;
653
p->range[3].range.min =
654
-get_s16(&full_scale->mx) * 100;
655
p->range[3].range.max =
656
get_s16(&full_scale->mx) * 100;
657
p->range[4].range.min =
658
-get_s16(&full_scale->my) * 100;
659
p->range[4].range.max =
660
get_s16(&full_scale->my) * 100;
661
p->range[5].range.min =
662
-get_s16(&full_scale->mz) * 100;
663
p->range[5].range.max =
664
get_s16(&full_scale->mz) * 100;
665
p->range[6].range.min = -get_s16(&full_scale->v1) * 100; /* ?? */
666
p->range[6].range.max = get_s16(&full_scale->v1) * 100; /* ?? */
667
p->range[7].range.min = -get_s16(&full_scale->v2) * 100; /* ?? */
668
p->range[7].range.max = get_s16(&full_scale->v2) * 100; /* ?? */
669
p->range[8].range.min = 0;
670
p->range[8].range.max = 65535;
674
for (i = 0; i < 9; i++) {
675
printk("%d %d - %d\n",
686
use_offset(channel, 0);
688
state_jr3_init_use_offset_complete;
689
result = poll_delay_min_max(40, 100); /* Allow 40 ms for completion */
693
case state_jr3_init_use_offset_complete:{
694
if (!is_complete(channel)) {
696
("state_jr3_init_use_offset_complete complete = %d\n",
697
is_complete(channel));
698
result = poll_delay_min_max(20, 100);
701
("Default offsets %d %d %d %d %d %d\n",
702
get_s16(&channel->offsets.fx),
703
get_s16(&channel->offsets.fy),
704
get_s16(&channel->offsets.fz),
705
get_s16(&channel->offsets.mx),
706
get_s16(&channel->offsets.my),
707
get_s16(&channel->offsets.mz));
709
set_s16(&channel->offsets.fx, 0);
710
set_s16(&channel->offsets.fy, 0);
711
set_s16(&channel->offsets.fz, 0);
712
set_s16(&channel->offsets.mx, 0);
713
set_s16(&channel->offsets.my, 0);
714
set_s16(&channel->offsets.mz, 0);
718
p->state = state_jr3_done;
722
case state_jr3_done:{
723
poll_delay_min_max(10000, 20000);
727
poll_delay_min_max(1000, 2000);
735
static void jr3_pci_poll_dev(unsigned long data)
738
struct comedi_device *dev = (struct comedi_device *)data;
739
struct jr3_pci_dev_private *devpriv = dev->private;
744
spin_lock_irqsave(&dev->spinlock, flags);
747
/* Poll all channels that are ready to be polled */
748
for (i = 0; i < devpriv->n_channels; i++) {
749
struct jr3_pci_subdev_private *subdevpriv =
750
dev->subdevices[i].private;
751
if (now > subdevpriv->next_time_min) {
752
struct poll_delay_t sub_delay;
754
sub_delay = jr3_pci_poll_subdevice(&dev->subdevices[i]);
755
subdevpriv->next_time_min =
756
jiffies + msecs_to_jiffies(sub_delay.min);
757
subdevpriv->next_time_max =
758
jiffies + msecs_to_jiffies(sub_delay.max);
759
if (sub_delay.max && sub_delay.max < delay) {
761
* Wake up as late as possible -> poll as many channels as possible
764
delay = sub_delay.max;
768
spin_unlock_irqrestore(&dev->spinlock, flags);
770
devpriv->timer.expires = jiffies + msecs_to_jiffies(delay);
771
add_timer(&devpriv->timer);
774
static int jr3_pci_attach(struct comedi_device *dev,
775
struct comedi_devconfig *it)
778
struct pci_dev *card = NULL;
779
int opt_bus, opt_slot, i;
780
struct jr3_pci_dev_private *devpriv;
782
printk("comedi%d: jr3_pci\n", dev->minor);
784
opt_bus = it->options[0];
785
opt_slot = it->options[1];
787
if (sizeof(struct jr3_channel) != 0xc00) {
788
printk("sizeof(struct jr3_channel) = %x [expected %x]\n",
789
(unsigned)sizeof(struct jr3_channel), 0xc00);
793
result = alloc_private(dev, sizeof(struct jr3_pci_dev_private));
797
devpriv = dev->private;
798
init_timer(&devpriv->timer);
800
card = pci_get_device(PCI_VENDOR_ID_JR3, PCI_ANY_ID, card);
805
switch (card->device) {
806
case PCI_DEVICE_ID_JR3_1_CHANNEL:{
807
devpriv->n_channels = 1;
810
case PCI_DEVICE_ID_JR3_1_CHANNEL_NEW:{
811
devpriv->n_channels = 1;
814
case PCI_DEVICE_ID_JR3_2_CHANNEL:{
815
devpriv->n_channels = 2;
818
case PCI_DEVICE_ID_JR3_3_CHANNEL:{
819
devpriv->n_channels = 3;
822
case PCI_DEVICE_ID_JR3_4_CHANNEL:{
823
devpriv->n_channels = 4;
827
devpriv->n_channels = 0;
830
if (devpriv->n_channels >= 1) {
831
if (opt_bus == 0 && opt_slot == 0) {
832
/* Take first available card */
834
} else if (opt_bus == card->bus->number &&
835
opt_slot == PCI_SLOT(card->devfn)) {
836
/* Take requested card */
843
printk(" no jr3_pci found\n");
846
devpriv->pci_dev = card;
847
dev->board_name = "jr3_pci";
850
result = comedi_pci_enable(card, "jr3_pci");
854
devpriv->pci_enabled = 1;
855
devpriv->iobase = ioremap(pci_resource_start(card, 0),
856
offsetof(struct jr3_t, channel[devpriv->n_channels]));
857
if (!devpriv->iobase)
860
result = alloc_subdevices(dev, devpriv->n_channels);
864
dev->open = jr3_pci_open;
865
for (i = 0; i < devpriv->n_channels; i++) {
866
dev->subdevices[i].type = COMEDI_SUBD_AI;
867
dev->subdevices[i].subdev_flags = SDF_READABLE | SDF_GROUND;
868
dev->subdevices[i].n_chan = 8 * 7 + 2;
869
dev->subdevices[i].insn_read = jr3_pci_ai_insn_read;
870
dev->subdevices[i].private =
871
kzalloc(sizeof(struct jr3_pci_subdev_private), GFP_KERNEL);
872
if (dev->subdevices[i].private) {
873
struct jr3_pci_subdev_private *p;
876
p = dev->subdevices[i].private;
877
p->channel = &devpriv->iobase->channel[i].data;
878
printk("p->channel %p %p (%tx)\n",
879
p->channel, devpriv->iobase,
880
((char *)(p->channel) -
881
(char *)(devpriv->iobase)));
883
for (j = 0; j < 8; j++) {
886
p->range[j].length = 1;
887
p->range[j].range.min = -1000000;
888
p->range[j].range.max = 1000000;
889
for (k = 0; k < 7; k++) {
890
p->range_table_list[j + k * 8] =
891
(struct comedi_lrange *)&p->
893
p->maxdata_list[j + k * 8] = 0x7fff;
896
p->range[8].length = 1;
897
p->range[8].range.min = 0;
898
p->range[8].range.max = 65536;
900
p->range_table_list[56] =
901
(struct comedi_lrange *)&p->range[8];
902
p->range_table_list[57] =
903
(struct comedi_lrange *)&p->range[8];
904
p->maxdata_list[56] = 0xffff;
905
p->maxdata_list[57] = 0xffff;
906
/* Channel specific range and maxdata */
907
dev->subdevices[i].range_table = 0;
908
dev->subdevices[i].range_table_list =
910
dev->subdevices[i].maxdata = 0;
911
dev->subdevices[i].maxdata_list = p->maxdata_list;
916
devpriv->iobase->channel[0].reset = 0;
918
result = comedi_load_firmware(dev, "jr3pci.idm", jr3_download_firmware);
919
printk("Firmare load %d\n", result);
924
* TODO: use firmware to load preferred offset tables. Suggested
926
* model serial Fx Fy Fz Mx My Mz\n
928
* comedi_load_firmware(dev, "jr3_offsets_table", jr3_download_firmware);
932
* It takes a few milliseconds for software to settle as much as we
933
* can read firmware version
935
msleep_interruptible(25);
936
for (i = 0; i < 0x18; i++) {
938
get_u16(&devpriv->iobase->channel[0].
939
data.copyright[i]) >> 8);
942
/* Start card timer */
943
for (i = 0; i < devpriv->n_channels; i++) {
944
struct jr3_pci_subdev_private *p = dev->subdevices[i].private;
946
p->next_time_min = jiffies + msecs_to_jiffies(500);
947
p->next_time_max = jiffies + msecs_to_jiffies(2000);
950
devpriv->timer.data = (unsigned long)dev;
951
devpriv->timer.function = jr3_pci_poll_dev;
952
devpriv->timer.expires = jiffies + msecs_to_jiffies(1000);
953
add_timer(&devpriv->timer);
959
MODULE_FIRMWARE("comedi/jr3pci.idm");
961
static int jr3_pci_detach(struct comedi_device *dev)
964
struct jr3_pci_dev_private *devpriv = dev->private;
966
printk("comedi%d: jr3_pci: remove\n", dev->minor);
968
del_timer_sync(&devpriv->timer);
970
if (dev->subdevices) {
971
for (i = 0; i < devpriv->n_channels; i++)
972
kfree(dev->subdevices[i].private);
976
iounmap((void *)devpriv->iobase);
977
if (devpriv->pci_enabled)
978
comedi_pci_disable(devpriv->pci_dev);
980
if (devpriv->pci_dev)
981
pci_dev_put(devpriv->pci_dev);
986
static int __devinit driver_jr3_pci_pci_probe(struct pci_dev *dev,
987
const struct pci_device_id *ent)
989
return comedi_pci_auto_config(dev, driver_jr3_pci.driver_name);
992
static void __devexit driver_jr3_pci_pci_remove(struct pci_dev *dev)
994
comedi_pci_auto_unconfig(dev);
997
static struct pci_driver driver_jr3_pci_pci_driver = {
998
.id_table = jr3_pci_pci_table,
999
.probe = &driver_jr3_pci_pci_probe,
1000
.remove = __devexit_p(&driver_jr3_pci_pci_remove)
1003
static int __init driver_jr3_pci_init_module(void)
1007
retval = comedi_driver_register(&driver_jr3_pci);
1011
driver_jr3_pci_pci_driver.name = (char *)driver_jr3_pci.driver_name;
1012
return pci_register_driver(&driver_jr3_pci_pci_driver);
1015
static void __exit driver_jr3_pci_cleanup_module(void)
1017
pci_unregister_driver(&driver_jr3_pci_pci_driver);
1018
comedi_driver_unregister(&driver_jr3_pci);
1021
module_init(driver_jr3_pci_init_module);
1022
module_exit(driver_jr3_pci_cleanup_module);
1024
MODULE_AUTHOR("Comedi http://www.comedi.org");
1025
MODULE_DESCRIPTION("Comedi low-level driver");
1026
MODULE_LICENSE("GPL");