Version:  2.0.40 2.2.26 2.4.37 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 3.16 3.17

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 
200         result.fx = get_s16(&channel->min_full_scale.fx);
201         result.fy = get_s16(&channel->min_full_scale.fy);
202         result.fz = get_s16(&channel->min_full_scale.fz);
203         result.mx = get_s16(&channel->min_full_scale.mx);
204         result.my = get_s16(&channel->min_full_scale.my);
205         result.mz = get_s16(&channel->min_full_scale.mz);
206         return result;
207 }
208 
209 static struct six_axis_t get_max_full_scales(struct jr3_channel __iomem
210                                              *channel)
211 {
212         struct six_axis_t result;
213 
214         result.fx = get_s16(&channel->max_full_scale.fx);
215         result.fy = get_s16(&channel->max_full_scale.fy);
216         result.fz = get_s16(&channel->max_full_scale.fz);
217         result.mx = get_s16(&channel->max_full_scale.mx);
218         result.my = get_s16(&channel->max_full_scale.my);
219         result.mz = get_s16(&channel->max_full_scale.mz);
220         return result;
221 }
222 
223 static unsigned int jr3_pci_ai_read_chan(struct comedi_device *dev,
224                                          struct comedi_subdevice *s,
225                                          unsigned int chan)
226 {
227         struct jr3_pci_subdev_private *spriv = s->private;
228         unsigned int val = 0;
229 
230         if (spriv->state != state_jr3_done)
231                 return 0;
232 
233         if (chan < 56) {
234                 unsigned int axis = chan % 8;
235                 unsigned filter = chan / 8;
236 
237                 switch (axis) {
238                 case 0:
239                         val = get_s16(&spriv->channel->filter[filter].fx);
240                         break;
241                 case 1:
242                         val = get_s16(&spriv->channel->filter[filter].fy);
243                         break;
244                 case 2:
245                         val = get_s16(&spriv->channel->filter[filter].fz);
246                         break;
247                 case 3:
248                         val = get_s16(&spriv->channel->filter[filter].mx);
249                         break;
250                 case 4:
251                         val = get_s16(&spriv->channel->filter[filter].my);
252                         break;
253                 case 5:
254                         val = get_s16(&spriv->channel->filter[filter].mz);
255                         break;
256                 case 6:
257                         val = get_s16(&spriv->channel->filter[filter].v1);
258                         break;
259                 case 7:
260                         val = get_s16(&spriv->channel->filter[filter].v2);
261                         break;
262                 }
263                 val += 0x4000;
264         } else if (chan == 56) {
265                 val = get_u16(&spriv->channel->model_no);
266         } else if (chan == 57) {
267                 val = get_u16(&spriv->channel->serial_no);
268         }
269 
270         return val;
271 }
272 
273 static int jr3_pci_ai_insn_read(struct comedi_device *dev,
274                                 struct comedi_subdevice *s,
275                                 struct comedi_insn *insn,
276                                 unsigned int *data)
277 {
278         struct jr3_pci_subdev_private *spriv = s->private;
279         unsigned int chan = CR_CHAN(insn->chanspec);
280         u16 errors;
281         int i;
282 
283         if (!spriv)
284                 return -EINVAL;
285 
286         errors = get_u16(&spriv->channel->errors);
287         if (spriv->state != state_jr3_done ||
288             (errors & (watch_dog | watch_dog2 | sensor_change))) {
289                 /* No sensor or sensor changed */
290                 if (spriv->state == state_jr3_done) {
291                         /* Restart polling */
292                         spriv->state = state_jr3_poll;
293                 }
294                 return -EAGAIN;
295         }
296 
297         for (i = 0; i < insn->n; i++)
298                 data[i] = jr3_pci_ai_read_chan(dev, s, chan);
299 
300         return insn->n;
301 }
302 
303 static int jr3_pci_open(struct comedi_device *dev)
304 {
305         struct jr3_pci_subdev_private *spriv;
306         struct comedi_subdevice *s;
307         int i;
308 
309         dev_dbg(dev->class_dev, "jr3_pci_open\n");
310         for (i = 0; i < dev->n_subdevices; i++) {
311                 s = &dev->subdevices[i];
312                 spriv = s->private;
313                 if (spriv)
314                         dev_dbg(dev->class_dev, "serial: %p %d (%d)\n",
315                                 spriv, spriv->serial_no, s->index);
316         }
317         return 0;
318 }
319 
320 static int read_idm_word(const u8 *data, size_t size, int *pos,
321                          unsigned int *val)
322 {
323         int result = 0;
324         int value;
325 
326         if (pos && val) {
327                 /*  Skip over non hex */
328                 for (; *pos < size && !isxdigit(data[*pos]); (*pos)++)
329                         ;
330                 /*  Collect value */
331                 *val = 0;
332                 for (; *pos < size; (*pos)++) {
333                         value = hex_to_bin(data[*pos]);
334                         if (value >= 0) {
335                                 result = 1;
336                                 *val = (*val << 4) + value;
337                         } else {
338                                 break;
339                         }
340                 }
341         }
342         return result;
343 }
344 
345 static int jr3_check_firmware(struct comedi_device *dev,
346                               const u8 *data, size_t size)
347 {
348         int more = 1;
349         int pos = 0;
350 
351         /*
352          * IDM file format is:
353          *   { count, address, data <count> } *
354          *   ffff
355          */
356         while (more) {
357                 unsigned int count = 0;
358                 unsigned int addr = 0;
359 
360                 more = more && read_idm_word(data, size, &pos, &count);
361                 if (more && count == 0xffff)
362                         return 0;
363 
364                 more = more && read_idm_word(data, size, &pos, &addr);
365                 while (more && count > 0) {
366                         unsigned int dummy = 0;
367 
368                         more = more && read_idm_word(data, size, &pos, &dummy);
369                         count--;
370                 }
371         }
372 
373         return -ENODATA;
374 }
375 
376 static void jr3_write_firmware(struct comedi_device *dev,
377                                int subdev, const u8 *data, size_t size)
378 {
379         struct jr3_pci_dev_private *devpriv = dev->private;
380         struct jr3_t __iomem *iobase = devpriv->iobase;
381         u32 __iomem *lo;
382         u32 __iomem *hi;
383         int more = 1;
384         int pos = 0;
385 
386         while (more) {
387                 unsigned int count = 0;
388                 unsigned int addr = 0;
389 
390                 more = more && read_idm_word(data, size, &pos, &count);
391                 if (more && count == 0xffff)
392                         return;
393 
394                 more = more && read_idm_word(data, size, &pos, &addr);
395 
396                 dev_dbg(dev->class_dev, "Loading#%d %4.4x bytes at %4.4x\n",
397                         subdev, count, addr);
398 
399                 while (more && count > 0) {
400                         if (addr & 0x4000) {
401                                 /* 16 bit data, never seen in real life!! */
402                                 unsigned int data1 = 0;
403 
404                                 more = more &&
405                                        read_idm_word(data, size, &pos, &data1);
406                                 count--;
407                                 /* jr3[addr + 0x20000 * pnum] = data1; */
408                         } else {
409                                 /* Download 24 bit program */
410                                 unsigned int data1 = 0;
411                                 unsigned int data2 = 0;
412 
413                                 lo = &iobase->channel[subdev].program_lo[addr];
414                                 hi = &iobase->channel[subdev].program_hi[addr];
415 
416                                 more = more &&
417                                        read_idm_word(data, size, &pos, &data1);
418                                 more = more &&
419                                        read_idm_word(data, size, &pos, &data2);
420                                 count -= 2;
421                                 if (more) {
422                                         set_u16(lo, data1);
423                                         udelay(1);
424                                         set_u16(hi, data2);
425                                         udelay(1);
426                                 }
427                         }
428                         addr++;
429                 }
430         }
431 }
432 
433 static int jr3_download_firmware(struct comedi_device *dev,
434                                  const u8 *data, size_t size,
435                                  unsigned long context)
436 {
437         int subdev;
438         int ret;
439 
440         /* verify IDM file format */
441         ret = jr3_check_firmware(dev, data, size);
442         if (ret)
443                 return ret;
444 
445         /* write firmware to each subdevice */
446         for (subdev = 0; subdev < dev->n_subdevices; subdev++)
447                 jr3_write_firmware(dev, subdev, data, size);
448 
449         return 0;
450 }
451 
452 static struct jr3_pci_poll_delay jr3_pci_poll_subdevice(struct comedi_subdevice *s)
453 {
454         struct jr3_pci_subdev_private *spriv = s->private;
455         struct jr3_pci_poll_delay result = poll_delay_min_max(1000, 2000);
456         struct jr3_channel __iomem *channel;
457         u16 model_no;
458         u16 serial_no;
459         int errors;
460         int i;
461 
462         if (!spriv)
463                 return result;
464 
465         channel = spriv->channel;
466         errors = get_u16(&channel->errors);
467 
468         if (errors != spriv->errors)
469                 spriv->errors = errors;
470 
471         /* Sensor communication lost? force poll mode */
472         if (errors & (watch_dog | watch_dog2 | sensor_change))
473                 spriv->state = state_jr3_poll;
474 
475         switch (spriv->state) {
476         case state_jr3_poll:
477                 model_no = get_u16(&channel->model_no);
478                 serial_no = get_u16(&channel->serial_no);
479 
480                 if ((errors & (watch_dog | watch_dog2)) ||
481                     model_no == 0 || serial_no == 0) {
482                         /*
483                          * Still no sensor, keep on polling.
484                          * Since it takes up to 10 seconds for offsets to
485                          * stabilize, polling each second should suffice.
486                          */
487                 } else {
488                         spriv->retries = 0;
489                         spriv->state = state_jr3_init_wait_for_offset;
490                 }
491                 break;
492         case state_jr3_init_wait_for_offset:
493                 spriv->retries++;
494                 if (spriv->retries < 10) {
495                         /*
496                          * Wait for offeset to stabilize
497                          * (< 10 s according to manual)
498                          */
499                 } else {
500                         struct jr3_pci_transform transf;
501 
502                         spriv->model_no = get_u16(&channel->model_no);
503                         spriv->serial_no = get_u16(&channel->serial_no);
504 
505                         /* Transformation all zeros */
506                         for (i = 0; i < ARRAY_SIZE(transf.link); i++) {
507                                 transf.link[i].link_type = (enum link_types)0;
508                                 transf.link[i].link_amount = 0;
509                         }
510 
511                         set_transforms(channel, transf, 0);
512                         use_transform(channel, 0);
513                         spriv->state = state_jr3_init_transform_complete;
514                         /* Allow 20 ms for completion */
515                         result = poll_delay_min_max(20, 100);
516                 }
517                 break;
518         case state_jr3_init_transform_complete:
519                 if (!is_complete(channel)) {
520                         result = poll_delay_min_max(20, 100);
521                 } else {
522                         /* Set full scale */
523                         struct six_axis_t min_full_scale;
524                         struct six_axis_t max_full_scale;
525 
526                         min_full_scale = get_min_full_scales(channel);
527                         max_full_scale = get_max_full_scales(channel);
528                         set_full_scales(channel, max_full_scale);
529 
530                         spriv->state = state_jr3_init_set_full_scale_complete;
531                         /* Allow 20 ms for completion */
532                         result = poll_delay_min_max(20, 100);
533                 }
534                 break;
535         case state_jr3_init_set_full_scale_complete:
536                 if (!is_complete(channel)) {
537                         result = poll_delay_min_max(20, 100);
538                 } else {
539                         struct force_array __iomem *fs = &channel->full_scale;
540 
541                         /* Use ranges in kN or we will overflow around 2000N! */
542                         spriv->range[0].range.min = -get_s16(&fs->fx) * 1000;
543                         spriv->range[0].range.max = get_s16(&fs->fx) * 1000;
544                         spriv->range[1].range.min = -get_s16(&fs->fy) * 1000;
545                         spriv->range[1].range.max = get_s16(&fs->fy) * 1000;
546                         spriv->range[2].range.min = -get_s16(&fs->fz) * 1000;
547                         spriv->range[2].range.max = get_s16(&fs->fz) * 1000;
548                         spriv->range[3].range.min = -get_s16(&fs->mx) * 100;
549                         spriv->range[3].range.max = get_s16(&fs->mx) * 100;
550                         spriv->range[4].range.min = -get_s16(&fs->my) * 100;
551                         spriv->range[4].range.max = get_s16(&fs->my) * 100;
552                         spriv->range[5].range.min = -get_s16(&fs->mz) * 100;
553                         /* the next five are questionable */
554                         spriv->range[5].range.max = get_s16(&fs->mz) * 100;
555                         spriv->range[6].range.min = -get_s16(&fs->v1) * 100;
556                         spriv->range[6].range.max = get_s16(&fs->v1) * 100;
557                         spriv->range[7].range.min = -get_s16(&fs->v2) * 100;
558                         spriv->range[7].range.max = get_s16(&fs->v2) * 100;
559                         spriv->range[8].range.min = 0;
560                         spriv->range[8].range.max = 65535;
561 
562                         use_offset(channel, 0);
563                         spriv->state = state_jr3_init_use_offset_complete;
564                         /* Allow 40 ms for completion */
565                         result = poll_delay_min_max(40, 100);
566                 }
567                 break;
568         case state_jr3_init_use_offset_complete:
569                 if (!is_complete(channel)) {
570                         result = poll_delay_min_max(20, 100);
571                 } else {
572                         set_s16(&channel->offsets.fx, 0);
573                         set_s16(&channel->offsets.fy, 0);
574                         set_s16(&channel->offsets.fz, 0);
575                         set_s16(&channel->offsets.mx, 0);
576                         set_s16(&channel->offsets.my, 0);
577                         set_s16(&channel->offsets.mz, 0);
578 
579                         set_offset(channel);
580 
581                         spriv->state = state_jr3_done;
582                 }
583                 break;
584         case state_jr3_done:
585                 result = poll_delay_min_max(10000, 20000);
586                 break;
587         default:
588                 break;
589         }
590 
591         return result;
592 }
593 
594 static void jr3_pci_poll_dev(unsigned long data)
595 {
596         struct comedi_device *dev = (struct comedi_device *)data;
597         struct jr3_pci_dev_private *devpriv = dev->private;
598         struct jr3_pci_subdev_private *spriv;
599         struct comedi_subdevice *s;
600         unsigned long flags;
601         unsigned long now;
602         int delay;
603         int i;
604 
605         spin_lock_irqsave(&dev->spinlock, flags);
606         delay = 1000;
607         now = jiffies;
608 
609         /* Poll all channels that are ready to be polled */
610         for (i = 0; i < dev->n_subdevices; i++) {
611                 s = &dev->subdevices[i];
612                 spriv = s->private;
613 
614                 if (now > spriv->next_time_min) {
615                         struct jr3_pci_poll_delay sub_delay;
616 
617                         sub_delay = jr3_pci_poll_subdevice(s);
618 
619                         spriv->next_time_min = jiffies +
620                                                msecs_to_jiffies(sub_delay.min);
621                         spriv->next_time_max = jiffies +
622                                                msecs_to_jiffies(sub_delay.max);
623 
624                         if (sub_delay.max && sub_delay.max < delay)
625                                 /*
626                                  * Wake up as late as possible ->
627                                  * poll as many channels as possible at once.
628                                  */
629                                 delay = sub_delay.max;
630                 }
631         }
632         spin_unlock_irqrestore(&dev->spinlock, flags);
633 
634         devpriv->timer.expires = jiffies + msecs_to_jiffies(delay);
635         add_timer(&devpriv->timer);
636 }
637 
638 static struct jr3_pci_subdev_private *
639 jr3_pci_alloc_spriv(struct comedi_device *dev, struct comedi_subdevice *s)
640 {
641         struct jr3_pci_dev_private *devpriv = dev->private;
642         struct jr3_pci_subdev_private *spriv;
643         int j;
644         int k;
645 
646         spriv = comedi_alloc_spriv(s, sizeof(*spriv));
647         if (!spriv)
648                 return NULL;
649 
650         spriv->channel = &devpriv->iobase->channel[s->index].data;
651 
652         for (j = 0; j < 8; j++) {
653                 spriv->range[j].length = 1;
654                 spriv->range[j].range.min = -1000000;
655                 spriv->range[j].range.max = 1000000;
656 
657                 for (k = 0; k < 7; k++) {
658                         spriv->range_table_list[j + k * 8] =
659                                 (struct comedi_lrange *)&spriv->range[j];
660                         spriv->maxdata_list[j + k * 8] = 0x7fff;
661                 }
662         }
663         spriv->range[8].length = 1;
664         spriv->range[8].range.min = 0;
665         spriv->range[8].range.max = 65536;
666 
667         spriv->range_table_list[56] = (struct comedi_lrange *)&spriv->range[8];
668         spriv->range_table_list[57] = (struct comedi_lrange *)&spriv->range[8];
669         spriv->maxdata_list[56] = 0xffff;
670         spriv->maxdata_list[57] = 0xffff;
671 
672         dev_dbg(dev->class_dev, "p->channel %p %p (%tx)\n",
673                 spriv->channel, devpriv->iobase,
674                 ((char __iomem *)spriv->channel -
675                  (char __iomem *)devpriv->iobase));
676 
677         return spriv;
678 }
679 
680 static int jr3_pci_auto_attach(struct comedi_device *dev,
681                                unsigned long context)
682 {
683         struct pci_dev *pcidev = comedi_to_pci_dev(dev);
684         static const struct jr3_pci_board *board = NULL;
685         struct jr3_pci_dev_private *devpriv;
686         struct jr3_pci_subdev_private *spriv;
687         struct comedi_subdevice *s;
688         int ret;
689         int i;
690 
691         if (sizeof(struct jr3_channel) != 0xc00) {
692                 dev_err(dev->class_dev,
693                         "sizeof(struct jr3_channel) = %x [expected %x]\n",
694                         (unsigned)sizeof(struct jr3_channel), 0xc00);
695                 return -EINVAL;
696         }
697 
698         if (context < ARRAY_SIZE(jr3_pci_boards))
699                 board = &jr3_pci_boards[context];
700         if (!board)
701                 return -ENODEV;
702         dev->board_ptr = board;
703         dev->board_name = board->name;
704 
705         devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
706         if (!devpriv)
707                 return -ENOMEM;
708 
709         init_timer(&devpriv->timer);
710 
711         ret = comedi_pci_enable(dev);
712         if (ret)
713                 return ret;
714 
715         devpriv->iobase = pci_ioremap_bar(pcidev, 0);
716         if (!devpriv->iobase)
717                 return -ENOMEM;
718 
719         ret = comedi_alloc_subdevices(dev, board->n_subdevs);
720         if (ret)
721                 return ret;
722 
723         dev->open = jr3_pci_open;
724         for (i = 0; i < dev->n_subdevices; i++) {
725                 s = &dev->subdevices[i];
726                 s->type         = COMEDI_SUBD_AI;
727                 s->subdev_flags = SDF_READABLE | SDF_GROUND;
728                 s->n_chan       = 8 * 7 + 2;
729                 s->insn_read    = jr3_pci_ai_insn_read;
730 
731                 spriv = jr3_pci_alloc_spriv(dev, s);
732                 if (spriv) {
733                         /* Channel specific range and maxdata */
734                         s->range_table_list     = spriv->range_table_list;
735                         s->maxdata_list         = spriv->maxdata_list;
736                 }
737         }
738 
739         /*  Reset DSP card */
740         writel(0, &devpriv->iobase->channel[0].reset);
741 
742         ret = comedi_load_firmware(dev, &comedi_to_pci_dev(dev)->dev,
743                                    "comedi/jr3pci.idm",
744                                    jr3_download_firmware, 0);
745         dev_dbg(dev->class_dev, "Firmare load %d\n", ret);
746         if (ret < 0)
747                 return ret;
748         /*
749          * TODO: use firmware to load preferred offset tables. Suggested
750          * format:
751          *     model serial Fx Fy Fz Mx My Mz\n
752          *
753          *     comedi_load_firmware(dev, &comedi_to_pci_dev(dev)->dev,
754          *                          "comedi/jr3_offsets_table",
755          *                          jr3_download_firmware, 1);
756          */
757 
758         /*
759          * It takes a few milliseconds for software to settle as much as we
760          * can read firmware version
761          */
762         msleep_interruptible(25);
763         for (i = 0; i < 0x18; i++) {
764                 dev_dbg(dev->class_dev, "%c\n",
765                         get_u16(&devpriv->iobase->channel[0].
766                                 data.copyright[i]) >> 8);
767         }
768 
769         /*  Start card timer */
770         for (i = 0; i < dev->n_subdevices; i++) {
771                 s = &dev->subdevices[i];
772                 spriv = s->private;
773 
774                 spriv->next_time_min = jiffies + msecs_to_jiffies(500);
775                 spriv->next_time_max = jiffies + msecs_to_jiffies(2000);
776         }
777 
778         devpriv->timer.data = (unsigned long)dev;
779         devpriv->timer.function = jr3_pci_poll_dev;
780         devpriv->timer.expires = jiffies + msecs_to_jiffies(1000);
781         add_timer(&devpriv->timer);
782 
783         return 0;
784 }
785 
786 static void jr3_pci_detach(struct comedi_device *dev)
787 {
788         struct jr3_pci_dev_private *devpriv = dev->private;
789 
790         if (devpriv) {
791                 del_timer_sync(&devpriv->timer);
792 
793                 if (devpriv->iobase)
794                         iounmap(devpriv->iobase);
795         }
796         comedi_pci_disable(dev);
797 }
798 
799 static struct comedi_driver jr3_pci_driver = {
800         .driver_name    = "jr3_pci",
801         .module         = THIS_MODULE,
802         .auto_attach    = jr3_pci_auto_attach,
803         .detach         = jr3_pci_detach,
804 };
805 
806 static int jr3_pci_pci_probe(struct pci_dev *dev,
807                              const struct pci_device_id *id)
808 {
809         return comedi_pci_auto_config(dev, &jr3_pci_driver, id->driver_data);
810 }
811 
812 static const struct pci_device_id jr3_pci_pci_table[] = {
813         { PCI_VDEVICE(JR3, 0x1111), BOARD_JR3_1 },
814         { PCI_VDEVICE(JR3, 0x3111), BOARD_JR3_1 },
815         { PCI_VDEVICE(JR3, 0x3112), BOARD_JR3_2 },
816         { PCI_VDEVICE(JR3, 0x3113), BOARD_JR3_3 },
817         { PCI_VDEVICE(JR3, 0x3114), BOARD_JR3_4 },
818         { 0 }
819 };
820 MODULE_DEVICE_TABLE(pci, jr3_pci_pci_table);
821 
822 static struct pci_driver jr3_pci_pci_driver = {
823         .name           = "jr3_pci",
824         .id_table       = jr3_pci_pci_table,
825         .probe          = jr3_pci_pci_probe,
826         .remove         = comedi_pci_auto_unconfig,
827 };
828 module_comedi_pci_driver(jr3_pci_driver, jr3_pci_pci_driver);
829 
830 MODULE_AUTHOR("Comedi http://www.comedi.org");
831 MODULE_DESCRIPTION("Comedi low-level driver");
832 MODULE_LICENSE("GPL");
833 MODULE_FIRMWARE("comedi/jr3pci.idm");
834 

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