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