Version:  2.0.40 2.2.26 2.4.37 2.6.39 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15

Linux/drivers/staging/comedi/drivers/jr3_pci.c

  1 /*
  2   comedi/drivers/jr3_pci.c
  3   hardware driver for JR3/PCI force sensor board
  4 
  5   COMEDI - Linux Control and Measurement Device Interface
  6   Copyright (C) 2007 Anders Blomdell <anders.blomdell@control.lth.se>
  7 
  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.
 12 
 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.
 17 */
 18 /*
 19  * Driver: jr3_pci
 20  * Description: JR3/PCI force sensor board
 21  * Author: Anders Blomdell <anders.blomdell@control.lth.se>
 22  * Updated: Thu, 01 Nov 2012 17:34:55 +0000
 23  * Status: works
 24  * Devices: [JR3] PCI force sensor board (jr3_pci)
 25  *
 26  * Configuration options:
 27  *   None
 28  *
 29  * Manual configuration of comedi devices is not supported by this
 30  * driver; supported PCI devices are configured as comedi devices
 31  * automatically.
 32  *
 33  * The DSP on the board requires initialization code, which can be
 34  * loaded by placing it in /lib/firmware/comedi.  The initialization
 35  * code should be somewhere on the media you got with your card.  One
 36  * version is available from http://www.comedi.org in the
 37  * comedi_nonfree_firmware tarball.  The file is called "jr3pci.idm".
 38  */
 39 
 40 #include <linux/kernel.h>
 41 #include <linux/module.h>
 42 #include <linux/pci.h>
 43 #include <linux/delay.h>
 44 #include <linux/ctype.h>
 45 #include <linux/jiffies.h>
 46 #include <linux/slab.h>
 47 #include <linux/timer.h>
 48 
 49 #include "../comedidev.h"
 50 
 51 #include "jr3_pci.h"
 52 
 53 #define PCI_VENDOR_ID_JR3 0x1762
 54 
 55 enum jr3_pci_boardid {
 56         BOARD_JR3_1,
 57         BOARD_JR3_2,
 58         BOARD_JR3_3,
 59         BOARD_JR3_4,
 60 };
 61 
 62 struct jr3_pci_board {
 63         const char *name;
 64         int n_subdevs;
 65 };
 66 
 67 static const struct jr3_pci_board jr3_pci_boards[] = {
 68         [BOARD_JR3_1] = {
 69                 .name           = "jr3_pci_1",
 70                 .n_subdevs      = 1,
 71         },
 72         [BOARD_JR3_2] = {
 73                 .name           = "jr3_pci_2",
 74                 .n_subdevs      = 2,
 75         },
 76         [BOARD_JR3_3] = {
 77                 .name           = "jr3_pci_3",
 78                 .n_subdevs      = 3,
 79         },
 80         [BOARD_JR3_4] = {
 81                 .name           = "jr3_pci_4",
 82                 .n_subdevs      = 4,
 83         },
 84 };
 85 
 86 struct jr3_pci_transform {
 87         struct {
 88                 u16 link_type;
 89                 s16 link_amount;
 90         } link[8];
 91 };
 92 
 93 struct jr3_pci_poll_delay {
 94         int min;
 95         int max;
 96 };
 97 
 98 struct jr3_pci_dev_private {
 99         struct jr3_t __iomem *iobase;
100         struct timer_list timer;
101 };
102 
103 struct jr3_pci_subdev_private {
104         struct jr3_channel __iomem *channel;
105         unsigned long next_time_min;
106         unsigned long next_time_max;
107         enum { state_jr3_poll,
108                 state_jr3_init_wait_for_offset,
109                 state_jr3_init_transform_complete,
110                 state_jr3_init_set_full_scale_complete,
111                 state_jr3_init_use_offset_complete,
112                 state_jr3_done
113         } state;
114         int serial_no;
115         int model_no;
116         struct {
117                 int length;
118                 struct comedi_krange range;
119         } range[9];
120         const struct comedi_lrange *range_table_list[8 * 7 + 2];
121         unsigned int maxdata_list[8 * 7 + 2];
122         u16 errors;
123         int retries;
124 };
125 
126 static struct jr3_pci_poll_delay poll_delay_min_max(int min, int max)
127 {
128         struct jr3_pci_poll_delay result;
129 
130         result.min = min;
131         result.max = max;
132         return result;
133 }
134 
135 static int is_complete(struct jr3_channel __iomem *channel)
136 {
137         return get_s16(&channel->command_word0) == 0;
138 }
139 
140 static void set_transforms(struct jr3_channel __iomem *channel,
141                            struct jr3_pci_transform transf, short num)
142 {
143         int i;
144 
145         num &= 0x000f;          /*  Make sure that 0 <= num <= 15 */
146         for (i = 0; i < 8; i++) {
147                 set_u16(&channel->transforms[num].link[i].link_type,
148                         transf.link[i].link_type);
149                 udelay(1);
150                 set_s16(&channel->transforms[num].link[i].link_amount,
151                         transf.link[i].link_amount);
152                 udelay(1);
153                 if (transf.link[i].link_type == end_x_form)
154                         break;
155         }
156 }
157 
158 static void use_transform(struct jr3_channel __iomem *channel,
159                           short transf_num)
160 {
161         set_s16(&channel->command_word0, 0x0500 + (transf_num & 0x000f));
162 }
163 
164 static void use_offset(struct jr3_channel __iomem *channel, short offset_num)
165 {
166         set_s16(&channel->command_word0, 0x0600 + (offset_num & 0x000f));
167 }
168 
169 static void set_offset(struct jr3_channel __iomem *channel)
170 {
171         set_s16(&channel->command_word0, 0x0700);
172 }
173 
174 struct six_axis_t {
175         s16 fx;
176         s16 fy;
177         s16 fz;
178         s16 mx;
179         s16 my;
180         s16 mz;
181 };
182 
183 static void set_full_scales(struct jr3_channel __iomem *channel,
184                             struct six_axis_t full_scale)
185 {
186         set_s16(&channel->full_scale.fx, full_scale.fx);
187         set_s16(&channel->full_scale.fy, full_scale.fy);
188         set_s16(&channel->full_scale.fz, full_scale.fz);
189         set_s16(&channel->full_scale.mx, full_scale.mx);
190         set_s16(&channel->full_scale.my, full_scale.my);
191         set_s16(&channel->full_scale.mz, full_scale.mz);
192         set_s16(&channel->command_word0, 0x0a00);
193 }
194 
195 static struct six_axis_t get_min_full_scales(struct jr3_channel __iomem
196                                              *channel)
197 {
198         struct six_axis_t result;
199         result.fx = get_s16(&channel->min_full_scale.fx);
200         result.fy = get_s16(&channel->min_full_scale.fy);
201         result.fz = get_s16(&channel->min_full_scale.fz);
202         result.mx = get_s16(&channel->min_full_scale.mx);
203         result.my = get_s16(&channel->min_full_scale.my);
204         result.mz = get_s16(&channel->min_full_scale.mz);
205         return result;
206 }
207 
208 static struct six_axis_t get_max_full_scales(struct jr3_channel __iomem
209                                              *channel)
210 {
211         struct six_axis_t result;
212         result.fx = get_s16(&channel->max_full_scale.fx);
213         result.fy = get_s16(&channel->max_full_scale.fy);
214         result.fz = get_s16(&channel->max_full_scale.fz);
215         result.mx = get_s16(&channel->max_full_scale.mx);
216         result.my = get_s16(&channel->max_full_scale.my);
217         result.mz = get_s16(&channel->max_full_scale.mz);
218         return result;
219 }
220 
221 static unsigned int jr3_pci_ai_read_chan(struct comedi_device *dev,
222                                          struct comedi_subdevice *s,
223                                          unsigned int chan)
224 {
225         struct jr3_pci_subdev_private *spriv = s->private;
226         unsigned int val = 0;
227 
228         if (spriv->state != state_jr3_done)
229                 return 0;
230 
231         if (chan < 56) {
232                 unsigned int axis = chan % 8;
233                 unsigned filter = chan / 8;
234 
235                 switch (axis) {
236                 case 0:
237                         val = get_s16(&spriv->channel->filter[filter].fx);
238                         break;
239                 case 1:
240                         val = get_s16(&spriv->channel->filter[filter].fy);
241                         break;
242                 case 2:
243                         val = get_s16(&spriv->channel->filter[filter].fz);
244                         break;
245                 case 3:
246                         val = get_s16(&spriv->channel->filter[filter].mx);
247                         break;
248                 case 4:
249                         val = get_s16(&spriv->channel->filter[filter].my);
250                         break;
251                 case 5:
252                         val = get_s16(&spriv->channel->filter[filter].mz);
253                         break;
254                 case 6:
255                         val = get_s16(&spriv->channel->filter[filter].v1);
256                         break;
257                 case 7:
258                         val = get_s16(&spriv->channel->filter[filter].v2);
259                         break;
260                 }
261                 val += 0x4000;
262         } else if (chan == 56) {
263                 val = get_u16(&spriv->channel->model_no);
264         } else if (chan == 57) {
265                 val = get_u16(&spriv->channel->serial_no);
266         }
267 
268         return val;
269 }
270 
271 static int jr3_pci_ai_insn_read(struct comedi_device *dev,
272                                 struct comedi_subdevice *s,
273                                 struct comedi_insn *insn,
274                                 unsigned int *data)
275 {
276         struct jr3_pci_subdev_private *spriv = s->private;
277         unsigned int chan = CR_CHAN(insn->chanspec);
278         u16 errors;
279         int i;
280 
281         if (!spriv)
282                 return -EINVAL;
283 
284         errors = get_u16(&spriv->channel->errors);
285         if (spriv->state != state_jr3_done ||
286             (errors & (watch_dog | watch_dog2 | sensor_change))) {
287                 /* No sensor or sensor changed */
288                 if (spriv->state == state_jr3_done) {
289                         /* Restart polling */
290                         spriv->state = state_jr3_poll;
291                 }
292                 return -EAGAIN;
293         }
294 
295         for (i = 0; i < insn->n; i++)
296                 data[i] = jr3_pci_ai_read_chan(dev, s, chan);
297 
298         return insn->n;
299 }
300 
301 static int jr3_pci_open(struct comedi_device *dev)
302 {
303         struct jr3_pci_subdev_private *spriv;
304         struct comedi_subdevice *s;
305         int i;
306 
307         dev_dbg(dev->class_dev, "jr3_pci_open\n");
308         for (i = 0; i < dev->n_subdevices; i++) {
309                 s = &dev->subdevices[i];
310                 spriv = s->private;
311                 if (spriv)
312                         dev_dbg(dev->class_dev, "serial: %p %d (%d)\n",
313                                 spriv, spriv->serial_no, s->index);
314         }
315         return 0;
316 }
317 
318 static int read_idm_word(const u8 *data, size_t size, int *pos,
319                          unsigned int *val)
320 {
321         int result = 0;
322         if (pos && val) {
323                 /*  Skip over non hex */
324                 for (; *pos < size && !isxdigit(data[*pos]); (*pos)++)
325                         ;
326                 /*  Collect value */
327                 *val = 0;
328                 for (; *pos < size; (*pos)++) {
329                         int value;
330                         value = hex_to_bin(data[*pos]);
331                         if (value >= 0) {
332                                 result = 1;
333                                 *val = (*val << 4) + value;
334                         } else {
335                                 break;
336                         }
337                 }
338         }
339         return result;
340 }
341 
342 static int jr3_check_firmware(struct comedi_device *dev,
343                               const u8 *data, size_t size)
344 {
345         int more = 1;
346         int pos = 0;
347 
348         /*
349          * IDM file format is:
350          *   { count, address, data <count> } *
351          *   ffff
352          */
353         while (more) {
354                 unsigned int count = 0;
355                 unsigned int addr = 0;
356 
357                 more = more && read_idm_word(data, size, &pos, &count);
358                 if (more && count == 0xffff)
359                         return 0;
360 
361                 more = more && read_idm_word(data, size, &pos, &addr);
362                 while (more && count > 0) {
363                         unsigned int dummy = 0;
364 
365                         more = more && read_idm_word(data, size, &pos, &dummy);
366                         count--;
367                 }
368         }
369 
370         return -ENODATA;
371 }
372 
373 static void jr3_write_firmware(struct comedi_device *dev,
374                                int subdev, const u8 *data, size_t size)
375 {
376         struct jr3_pci_dev_private *devpriv = dev->private;
377         struct jr3_t __iomem *iobase = devpriv->iobase;
378         u32 __iomem *lo;
379         u32 __iomem *hi;
380         int more = 1;
381         int pos = 0;
382 
383         while (more) {
384                 unsigned int count = 0;
385                 unsigned int addr = 0;
386 
387                 more = more && read_idm_word(data, size, &pos, &count);
388                 if (more && count == 0xffff)
389                         return;
390 
391                 more = more && read_idm_word(data, size, &pos, &addr);
392 
393                 dev_dbg(dev->class_dev, "Loading#%d %4.4x bytes at %4.4x\n",
394                         subdev, count, addr);
395 
396                 while (more && count > 0) {
397                         if (addr & 0x4000) {
398                                 /* 16 bit data, never seen in real life!! */
399                                 unsigned int data1 = 0;
400 
401                                 more = more &&
402                                        read_idm_word(data, size, &pos, &data1);
403                                 count--;
404                                 /* jr3[addr + 0x20000 * pnum] = data1; */
405                         } else {
406                                 /* Download 24 bit program */
407                                 unsigned int data1 = 0;
408                                 unsigned int data2 = 0;
409 
410                                 lo = &iobase->channel[subdev].program_lo[addr];
411                                 hi = &iobase->channel[subdev].program_hi[addr];
412 
413                                 more = more &&
414                                        read_idm_word(data, size, &pos, &data1);
415                                 more = more &&
416                                        read_idm_word(data, size, &pos, &data2);
417                                 count -= 2;
418                                 if (more) {
419                                         set_u16(lo, data1);
420                                         udelay(1);
421                                         set_u16(hi, data2);
422                                         udelay(1);
423                                 }
424                         }
425                         addr++;
426                 }
427         }
428 }
429 
430 static int jr3_download_firmware(struct comedi_device *dev,
431                                  const u8 *data, size_t size,
432                                  unsigned long context)
433 {
434         int subdev;
435         int ret;
436 
437         /* verify IDM file format */
438         ret = jr3_check_firmware(dev, data, size);
439         if (ret)
440                 return ret;
441 
442         /* write firmware to each subdevice */
443         for (subdev = 0; subdev < dev->n_subdevices; subdev++)
444                 jr3_write_firmware(dev, subdev, data, size);
445 
446         return 0;
447 }
448 
449 static struct jr3_pci_poll_delay jr3_pci_poll_subdevice(struct comedi_subdevice *s)
450 {
451         struct jr3_pci_subdev_private *spriv = s->private;
452         struct jr3_pci_poll_delay result = poll_delay_min_max(1000, 2000);
453         struct jr3_channel __iomem *channel;
454         u16 model_no;
455         u16 serial_no;
456         int errors;
457         int i;
458 
459         if (!spriv)
460                 return result;
461 
462         channel = spriv->channel;
463         errors = get_u16(&channel->errors);
464 
465         if (errors != spriv->errors)
466                 spriv->errors = errors;
467 
468         /* Sensor communication lost? force poll mode */
469         if (errors & (watch_dog | watch_dog2 | sensor_change))
470                 spriv->state = state_jr3_poll;
471 
472         switch (spriv->state) {
473         case state_jr3_poll:
474                 model_no = get_u16(&channel->model_no);
475                 serial_no = get_u16(&channel->serial_no);
476 
477                 if ((errors & (watch_dog | watch_dog2)) ||
478                     model_no == 0 || serial_no == 0) {
479                         /*
480                          * Still no sensor, keep on polling.
481                          * Since it takes up to 10 seconds for offsets to
482                          * stabilize, polling each second should suffice.
483                          */
484                 } else {
485                         spriv->retries = 0;
486                         spriv->state = state_jr3_init_wait_for_offset;
487                 }
488                 break;
489         case state_jr3_init_wait_for_offset:
490                 spriv->retries++;
491                 if (spriv->retries < 10) {
492                         /*
493                          * Wait for offeset to stabilize
494                          * (< 10 s according to manual)
495                          */
496                 } else {
497                         struct jr3_pci_transform transf;
498 
499                         spriv->model_no = get_u16(&channel->model_no);
500                         spriv->serial_no = get_u16(&channel->serial_no);
501 
502                         /* Transformation all zeros */
503                         for (i = 0; i < ARRAY_SIZE(transf.link); i++) {
504                                 transf.link[i].link_type = (enum link_types)0;
505                                 transf.link[i].link_amount = 0;
506                         }
507 
508                         set_transforms(channel, transf, 0);
509                         use_transform(channel, 0);
510                         spriv->state = state_jr3_init_transform_complete;
511                         /* Allow 20 ms for completion */
512                         result = poll_delay_min_max(20, 100);
513                 }
514                 break;
515         case state_jr3_init_transform_complete:
516                 if (!is_complete(channel)) {
517                         result = poll_delay_min_max(20, 100);
518                 } else {
519                         /* Set full scale */
520                         struct six_axis_t min_full_scale;
521                         struct six_axis_t max_full_scale;
522 
523                         min_full_scale = get_min_full_scales(channel);
524                         max_full_scale = get_max_full_scales(channel);
525                         set_full_scales(channel, max_full_scale);
526 
527                         spriv->state = state_jr3_init_set_full_scale_complete;
528                         /* Allow 20 ms for completion */
529                         result = poll_delay_min_max(20, 100);
530                 }
531                 break;
532         case state_jr3_init_set_full_scale_complete:
533                 if (!is_complete(channel)) {
534                         result = poll_delay_min_max(20, 100);
535                 } else {
536                         struct force_array __iomem *fs = &channel->full_scale;
537 
538                         /* Use ranges in kN or we will overflow around 2000N! */
539                         spriv->range[0].range.min = -get_s16(&fs->fx) * 1000;
540                         spriv->range[0].range.max = get_s16(&fs->fx) * 1000;
541                         spriv->range[1].range.min = -get_s16(&fs->fy) * 1000;
542                         spriv->range[1].range.max = get_s16(&fs->fy) * 1000;
543                         spriv->range[2].range.min = -get_s16(&fs->fz) * 1000;
544                         spriv->range[2].range.max = get_s16(&fs->fz) * 1000;
545                         spriv->range[3].range.min = -get_s16(&fs->mx) * 100;
546                         spriv->range[3].range.max = get_s16(&fs->mx) * 100;
547                         spriv->range[4].range.min = -get_s16(&fs->my) * 100;
548                         spriv->range[4].range.max = get_s16(&fs->my) * 100;
549                         spriv->range[5].range.min = -get_s16(&fs->mz) * 100;
550                         /* the next five are questionable */
551                         spriv->range[5].range.max = get_s16(&fs->mz) * 100;
552                         spriv->range[6].range.min = -get_s16(&fs->v1) * 100;
553                         spriv->range[6].range.max = get_s16(&fs->v1) * 100;
554                         spriv->range[7].range.min = -get_s16(&fs->v2) * 100;
555                         spriv->range[7].range.max = get_s16(&fs->v2) * 100;
556                         spriv->range[8].range.min = 0;
557                         spriv->range[8].range.max = 65535;
558 
559                         use_offset(channel, 0);
560                         spriv->state = state_jr3_init_use_offset_complete;
561                         /* Allow 40 ms for completion */
562                         result = poll_delay_min_max(40, 100);
563                 }
564                 break;
565         case state_jr3_init_use_offset_complete:
566                 if (!is_complete(channel)) {
567                         result = poll_delay_min_max(20, 100);
568                 } else {
569                         set_s16(&channel->offsets.fx, 0);
570                         set_s16(&channel->offsets.fy, 0);
571                         set_s16(&channel->offsets.fz, 0);
572                         set_s16(&channel->offsets.mx, 0);
573                         set_s16(&channel->offsets.my, 0);
574                         set_s16(&channel->offsets.mz, 0);
575 
576                         set_offset(channel);
577 
578                         spriv->state = state_jr3_done;
579                 }
580                 break;
581         case state_jr3_done:
582                 result = poll_delay_min_max(10000, 20000);
583                 break;
584         default:
585                 break;
586         }
587 
588         return result;
589 }
590 
591 static void jr3_pci_poll_dev(unsigned long data)
592 {
593         struct comedi_device *dev = (struct comedi_device *)data;
594         struct jr3_pci_dev_private *devpriv = dev->private;
595         struct jr3_pci_subdev_private *spriv;
596         struct comedi_subdevice *s;
597         unsigned long flags;
598         unsigned long now;
599         int delay;
600         int i;
601 
602         spin_lock_irqsave(&dev->spinlock, flags);
603         delay = 1000;
604         now = jiffies;
605 
606         /* Poll all channels that are ready to be polled */
607         for (i = 0; i < dev->n_subdevices; i++) {
608                 s = &dev->subdevices[i];
609                 spriv = s->private;
610 
611                 if (now > spriv->next_time_min) {
612                         struct jr3_pci_poll_delay sub_delay;
613 
614                         sub_delay = jr3_pci_poll_subdevice(s);
615 
616                         spriv->next_time_min = jiffies +
617                                                msecs_to_jiffies(sub_delay.min);
618                         spriv->next_time_max = jiffies +
619                                                msecs_to_jiffies(sub_delay.max);
620 
621                         if (sub_delay.max && sub_delay.max < delay)
622                                 /*
623                                  * Wake up as late as possible ->
624                                  * poll as many channels as possible at once.
625                                  */
626                                 delay = sub_delay.max;
627                 }
628         }
629         spin_unlock_irqrestore(&dev->spinlock, flags);
630 
631         devpriv->timer.expires = jiffies + msecs_to_jiffies(delay);
632         add_timer(&devpriv->timer);
633 }
634 
635 static struct jr3_pci_subdev_private *
636 jr3_pci_alloc_spriv(struct comedi_device *dev, struct comedi_subdevice *s)
637 {
638         struct jr3_pci_dev_private *devpriv = dev->private;
639         struct jr3_pci_subdev_private *spriv;
640         int j;
641         int k;
642 
643         spriv = comedi_alloc_spriv(s, sizeof(*spriv));
644         if (!spriv)
645                 return NULL;
646 
647         spriv->channel = &devpriv->iobase->channel[s->index].data;
648 
649         for (j = 0; j < 8; j++) {
650                 spriv->range[j].length = 1;
651                 spriv->range[j].range.min = -1000000;
652                 spriv->range[j].range.max = 1000000;
653 
654                 for (k = 0; k < 7; k++) {
655                         spriv->range_table_list[j + k * 8] =
656                                 (struct comedi_lrange *)&spriv->range[j];
657                         spriv->maxdata_list[j + k * 8] = 0x7fff;
658                 }
659         }
660         spriv->range[8].length = 1;
661         spriv->range[8].range.min = 0;
662         spriv->range[8].range.max = 65536;
663 
664         spriv->range_table_list[56] = (struct comedi_lrange *)&spriv->range[8];
665         spriv->range_table_list[57] = (struct comedi_lrange *)&spriv->range[8];
666         spriv->maxdata_list[56] = 0xffff;
667         spriv->maxdata_list[57] = 0xffff;
668 
669         dev_dbg(dev->class_dev, "p->channel %p %p (%tx)\n",
670                 spriv->channel, devpriv->iobase,
671                 ((char __iomem *)spriv->channel -
672                  (char __iomem *)devpriv->iobase));
673 
674         return spriv;
675 }
676 
677 static int jr3_pci_auto_attach(struct comedi_device *dev,
678                                unsigned long context)
679 {
680         struct pci_dev *pcidev = comedi_to_pci_dev(dev);
681         static const struct jr3_pci_board *board = NULL;
682         struct jr3_pci_dev_private *devpriv;
683         struct jr3_pci_subdev_private *spriv;
684         struct comedi_subdevice *s;
685         int ret;
686         int i;
687 
688         if (sizeof(struct jr3_channel) != 0xc00) {
689                 dev_err(dev->class_dev,
690                         "sizeof(struct jr3_channel) = %x [expected %x]\n",
691                         (unsigned)sizeof(struct jr3_channel), 0xc00);
692                 return -EINVAL;
693         }
694 
695         if (context < ARRAY_SIZE(jr3_pci_boards))
696                 board = &jr3_pci_boards[context];
697         if (!board)
698                 return -ENODEV;
699         dev->board_ptr = board;
700         dev->board_name = board->name;
701 
702         devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
703         if (!devpriv)
704                 return -ENOMEM;
705 
706         init_timer(&devpriv->timer);
707 
708         ret = comedi_pci_enable(dev);
709         if (ret)
710                 return ret;
711 
712         devpriv->iobase = pci_ioremap_bar(pcidev, 0);
713         if (!devpriv->iobase)
714                 return -ENOMEM;
715 
716         ret = comedi_alloc_subdevices(dev, board->n_subdevs);
717         if (ret)
718                 return ret;
719 
720         dev->open = jr3_pci_open;
721         for (i = 0; i < dev->n_subdevices; i++) {
722                 s = &dev->subdevices[i];
723                 s->type         = COMEDI_SUBD_AI;
724                 s->subdev_flags = SDF_READABLE | SDF_GROUND;
725                 s->n_chan       = 8 * 7 + 2;
726                 s->insn_read    = jr3_pci_ai_insn_read;
727 
728                 spriv = jr3_pci_alloc_spriv(dev, s);
729                 if (spriv) {
730                         /* Channel specific range and maxdata */
731                         s->range_table_list     = spriv->range_table_list;
732                         s->maxdata_list         = spriv->maxdata_list;
733                 }
734         }
735 
736         /*  Reset DSP card */
737         writel(0, &devpriv->iobase->channel[0].reset);
738 
739         ret = comedi_load_firmware(dev, &comedi_to_pci_dev(dev)->dev,
740                                    "comedi/jr3pci.idm",
741                                    jr3_download_firmware, 0);
742         dev_dbg(dev->class_dev, "Firmare load %d\n", ret);
743         if (ret < 0)
744                 return ret;
745         /*
746          * TODO: use firmware to load preferred offset tables. Suggested
747          * format:
748          *     model serial Fx Fy Fz Mx My Mz\n
749          *
750          *     comedi_load_firmware(dev, &comedi_to_pci_dev(dev)->dev,
751          *                          "comedi/jr3_offsets_table",
752          *                          jr3_download_firmware, 1);
753          */
754 
755         /*
756          * It takes a few milliseconds for software to settle as much as we
757          * can read firmware version
758          */
759         msleep_interruptible(25);
760         for (i = 0; i < 0x18; i++) {
761                 dev_dbg(dev->class_dev, "%c\n",
762                         get_u16(&devpriv->iobase->channel[0].
763                                 data.copyright[i]) >> 8);
764         }
765 
766         /*  Start card timer */
767         for (i = 0; i < dev->n_subdevices; i++) {
768                 s = &dev->subdevices[i];
769                 spriv = s->private;
770 
771                 spriv->next_time_min = jiffies + msecs_to_jiffies(500);
772                 spriv->next_time_max = jiffies + msecs_to_jiffies(2000);
773         }
774 
775         devpriv->timer.data = (unsigned long)dev;
776         devpriv->timer.function = jr3_pci_poll_dev;
777         devpriv->timer.expires = jiffies + msecs_to_jiffies(1000);
778         add_timer(&devpriv->timer);
779 
780         return 0;
781 }
782 
783 static void jr3_pci_detach(struct comedi_device *dev)
784 {
785         struct jr3_pci_dev_private *devpriv = dev->private;
786 
787         if (devpriv) {
788                 del_timer_sync(&devpriv->timer);
789 
790                 if (devpriv->iobase)
791                         iounmap(devpriv->iobase);
792         }
793         comedi_pci_disable(dev);
794 }
795 
796 static struct comedi_driver jr3_pci_driver = {
797         .driver_name    = "jr3_pci",
798         .module         = THIS_MODULE,
799         .auto_attach    = jr3_pci_auto_attach,
800         .detach         = jr3_pci_detach,
801 };
802 
803 static int jr3_pci_pci_probe(struct pci_dev *dev,
804                              const struct pci_device_id *id)
805 {
806         return comedi_pci_auto_config(dev, &jr3_pci_driver, id->driver_data);
807 }
808 
809 static const struct pci_device_id jr3_pci_pci_table[] = {
810         { PCI_VDEVICE(JR3, 0x1111), BOARD_JR3_1 },
811         { PCI_VDEVICE(JR3, 0x3111), BOARD_JR3_1 },
812         { PCI_VDEVICE(JR3, 0x3112), BOARD_JR3_2 },
813         { PCI_VDEVICE(JR3, 0x3113), BOARD_JR3_3 },
814         { PCI_VDEVICE(JR3, 0x3114), BOARD_JR3_4 },
815         { 0 }
816 };
817 MODULE_DEVICE_TABLE(pci, jr3_pci_pci_table);
818 
819 static struct pci_driver jr3_pci_pci_driver = {
820         .name           = "jr3_pci",
821         .id_table       = jr3_pci_pci_table,
822         .probe          = jr3_pci_pci_probe,
823         .remove         = comedi_pci_auto_unconfig,
824 };
825 module_comedi_pci_driver(jr3_pci_driver, jr3_pci_pci_driver);
826 
827 MODULE_AUTHOR("Comedi http://www.comedi.org");
828 MODULE_DESCRIPTION("Comedi low-level driver");
829 MODULE_LICENSE("GPL");
830 MODULE_FIRMWARE("comedi/jr3pci.idm");
831 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us