Got rid of unnecessary casts when initializing comedi_driver.board_name
[comedi.git] / comedi / drivers / adl_pci8164.c
1 /*
2     comedi/drivers/adl_pci8164.c
3
4     Hardware comedi driver fot PCI-8164 Adlink card
5     Copyright (C) 2004 Michel Lachine <mike@mikelachaine.ca>
6
7     This program is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation; either version 2 of the License, or
10     (at your option) any later version.
11
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16
17     You should have received a copy of the GNU General Public License
18     along with this program; if not, write to the Free Software
19     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 */
22 /*
23 Driver: adl_pci8164.o
24 Description: Driver for the Adlink PCI-8164 4 Axes Motion Control board
25 Devices: [ADLink] PCI-8164 (pci8164)
26 Author: Michel Lachaine <mike@mikelachaine.ca>
27 Status: experimental
28
29 Configuration Options:
30   none
31 */
32
33 #include <linux/comedidev.h>
34 #include <linux/pci.h>
35 #include <linux/delay.h>
36 #include "comedi_fc.h"
37 #include "8253.h"
38
39 #define PCI8164_AXIS_X  0x00
40 #define PCI8164_AXIS_Y  0x08
41 #define PCI8164_AXIS_Z  0x10
42 #define PCI8164_AXIS_U  0x18
43
44 #define PCI8164_MSTS    0x00
45 #define PCI8164_SSTS    0x02
46 #define PCI8164_BUF0    0x04
47 #define PCI8164_BUF1    0x06
48
49 #define PCI8164_CMD     0x00
50 #define PCI8164_OTP     0x02
51
52 #define PCI_DEVICE_ID_PCI8164 0x8164
53
54 typedef struct {
55         const char *name;
56         int  vendor_id;
57         int  device_id;
58 } adl_pci8164_board;
59
60 static adl_pci8164_board adl_pci8164_boards[] = {
61         { "pci8164", PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI8164 },
62 };
63
64 static struct pci_device_id adl_pci8164_pci_table[] __devinitdata = {
65         { PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI8164, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
66         { 0 }
67 };
68 MODULE_DEVICE_TABLE(pci, adl_pci8164_pci_table);
69
70 #define thisboard ((adl_pci8164_board *)dev->board_ptr)
71
72 typedef struct{
73         int data;
74         struct pci_dev *pci_dev;
75 } adl_pci8164_private;
76
77 #define devpriv ((adl_pci8164_private *)dev->private)
78
79 static int adl_pci8164_attach(comedi_device *dev,comedi_devconfig *it);
80 static int adl_pci8164_detach(comedi_device *dev);
81 static comedi_driver driver_adl_pci8164={
82         driver_name:    "adl_pci8164",
83         module:         THIS_MODULE,
84         attach:         adl_pci8164_attach,
85         detach:         adl_pci8164_detach,
86         num_names:  1,
87         board_name: &adl_pci8164_boards[0].name,
88         offset:     sizeof(adl_pci8164_board),
89 };
90
91 static int adl_pci8164_insn_read_msts(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn, lsampl_t *data);
92
93 static int adl_pci8164_insn_read_ssts(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn, lsampl_t *data);
94
95 static int adl_pci8164_insn_read_buf0(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn, lsampl_t *data);
96
97 static int adl_pci8164_insn_read_buf1(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn, lsampl_t *data);
98
99 static int adl_pci8164_insn_write_cmd(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn, lsampl_t *data);
100
101 static int adl_pci8164_insn_write_otp(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn, lsampl_t *data);
102
103 static int adl_pci8164_insn_write_buf0(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn, lsampl_t *data);
104
105 static int adl_pci8164_insn_write_buf1(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn, lsampl_t *data);
106
107 static int adl_pci8164_attach(comedi_device *dev,comedi_devconfig *it)
108 {
109         struct pci_dev *pcidev;
110         comedi_subdevice *s;
111
112         printk("comedi: attempt to attach...\n");
113         printk("comedi%d: adl_pci8164: board=%s\n",dev->minor, thisboard->name);
114
115         dev->board_name = thisboard->name;
116
117         if(alloc_private(dev,sizeof(adl_pci8164_private))<0)
118                 return -ENOMEM;
119
120         if(alloc_subdevices(dev, 4)<0)
121                 return -ENOMEM;
122
123         for(pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); pcidev != NULL;
124                 pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev))
125         {
126
127                 if ( pcidev->vendor == PCI_VENDOR_ID_ADLINK &&
128                      pcidev->device == PCI_DEVICE_ID_PCI8164 ) {
129                         devpriv->pci_dev = pcidev;
130                         if (pci_enable_device(pcidev) < 0) {
131                                 printk("comedi%d: Failed to enable PCI device\n", dev->minor);
132                                 return -EIO;
133                         }
134                         if (pci_request_regions(pcidev, "adl_pci8164") < 0) {
135                                 printk("comedi%d: I/O port conflict\n", dev->minor);
136                                 return -EIO;
137                         }
138                         dev->iobase = pci_resource_start ( pcidev, 2 );
139                         printk ( "comedi: base addr %4lx\n", dev->iobase );
140
141                         dev->board_ptr = adl_pci8164_boards + 0;
142
143                         s=dev->subdevices+0;
144                         s->type = COMEDI_SUBD_PROC;
145                         s->subdev_flags = SDF_READABLE|SDF_WRITABLE;
146                         s->n_chan = 4;
147                         s->maxdata = 0xffff;
148                         s->len_chanlist = 4;
149                         //s->range_table = &range_axis;
150                         s->insn_read = adl_pci8164_insn_read_msts;
151                         s->insn_write = adl_pci8164_insn_write_cmd;
152
153                         s=dev->subdevices+1;
154                         s->type = COMEDI_SUBD_PROC;
155                         s->subdev_flags = SDF_READABLE|SDF_WRITABLE;
156                         s->n_chan = 4;
157                         s->maxdata = 0xffff;
158                         s->len_chanlist = 4;
159                         //s->range_table = &range_axis;
160                         s->insn_read = adl_pci8164_insn_read_ssts;
161                         s->insn_write = adl_pci8164_insn_write_otp;
162
163                         s=dev->subdevices+2;
164                         s->type = COMEDI_SUBD_PROC;
165                         s->subdev_flags = SDF_READABLE|SDF_WRITABLE;
166                         s->n_chan = 4;
167                         s->maxdata = 0xffff;
168                         s->len_chanlist = 4;
169                         //s->range_table = &range_axis;
170                         s->insn_read = adl_pci8164_insn_read_buf0;
171                         s->insn_write = adl_pci8164_insn_write_buf0;
172
173                         s=dev->subdevices+3;
174                         s->type = COMEDI_SUBD_PROC;
175                         s->subdev_flags = SDF_READABLE|SDF_WRITABLE;
176                         s->n_chan = 4;
177                         s->maxdata = 0xffff;
178                         s->len_chanlist = 4;
179                         //s->range_table = &range_axis;
180                         s->insn_read = adl_pci8164_insn_read_buf1;
181                         s->insn_write = adl_pci8164_insn_write_buf1;
182
183                         break;
184                 }
185         }
186
187         printk("comedi: attached\n");
188
189         return 1;
190 }
191
192
193 static int adl_pci8164_detach(comedi_device *dev)
194 {
195         printk("comedi%d: pci8164: remove\n",dev->minor);
196
197         if (devpriv && devpriv->pci_dev) {
198                 if (dev->iobase) {
199                         pci_release_regions(devpriv->pci_dev);
200                         pci_disable_device(devpriv->pci_dev);
201                 }
202                 pci_dev_put(devpriv->pci_dev);
203         }
204
205         return 0;
206 }
207
208 static int adl_pci8164_insn_read_msts(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn, lsampl_t *data)
209 {
210   int axis, axis_reg;
211   char *axisname;
212
213         axis = CR_CHAN(insn->chanspec);
214
215         switch (axis)
216         {
217                 case 0: axis_reg = PCI8164_AXIS_X;
218                         axisname = "X";
219                         break;
220                 case 1: axis_reg = PCI8164_AXIS_Y;
221                         axisname = "Y";
222                         break;
223                 case 2: axis_reg = PCI8164_AXIS_Z;
224                         axisname = "Z";
225                         break;
226                 case 3: axis_reg = PCI8164_AXIS_U;
227                         axisname = "U";
228                         break;
229                 default: axis_reg = PCI8164_AXIS_X;
230                         axisname = "X";
231         }
232
233         data[0] = inw(dev->iobase + axis_reg + PCI8164_MSTS);
234         printk("comedi: pci8164 MSTS read -> %04X:%04X on axis %s\n", data[0], data[1], axisname);
235
236         return 2;
237 }
238
239 static int adl_pci8164_insn_read_ssts(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn, lsampl_t *data)
240 {
241         int axis, axis_reg;
242         char *axisname;
243
244         axis = CR_CHAN(insn->chanspec);
245
246         switch (axis)
247         {
248                 case 0: axis_reg = PCI8164_AXIS_X;
249                         axisname = "X";
250                         break;
251                 case 1: axis_reg = PCI8164_AXIS_Y;
252                         axisname = "Y";
253                         break;
254                 case 2: axis_reg = PCI8164_AXIS_Z;
255                         axisname = "Z";
256                         break;
257                 case 3: axis_reg = PCI8164_AXIS_U;
258                         axisname = "U";
259                         break;
260                 default: axis_reg = PCI8164_AXIS_X;
261                         axisname = "X";
262         }
263
264         data[0] = inw(dev->iobase + axis_reg + PCI8164_SSTS);
265         printk("comedi: pci8164 SSTS read -> %04X:%04X on axis %s\n", data[0], data[1], axisname);
266
267         return 2;
268 }
269
270 static int adl_pci8164_insn_read_buf0(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn, lsampl_t *data)
271 {
272         int axis, axis_reg;
273         char *axisname;
274
275         axis = CR_CHAN(insn->chanspec);
276
277         switch (axis)
278         {
279                 case 0: axis_reg = PCI8164_AXIS_X;
280                         axisname = "X";
281                         break;
282                 case 1: axis_reg = PCI8164_AXIS_Y;
283                         axisname = "Y";
284                         break;
285                 case 2: axis_reg = PCI8164_AXIS_Z;
286                         axisname = "Z";
287                         break;
288                 case 3: axis_reg = PCI8164_AXIS_U;
289                         axisname = "U";
290                         break;
291                 default: axis_reg = PCI8164_AXIS_X;
292                         axisname = "X";
293         }
294
295         data[0] = inw(dev->iobase + axis_reg + PCI8164_BUF0);
296         printk("comedi: pci8164 BUF0 read -> %04X:%04X on axis %s\n", data[0], data[1], axisname);
297
298         return 2;
299 }
300
301 static int adl_pci8164_insn_read_buf1(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn, lsampl_t *data)
302 {
303         int axis, axis_reg;
304
305         char *axisname;
306
307         axis = CR_CHAN(insn->chanspec);
308
309         switch (axis)
310         {
311                 case 0: axis_reg = PCI8164_AXIS_X;
312                         axisname = "X";
313                         break;
314                 case 1: axis_reg = PCI8164_AXIS_Y;
315                         axisname = "Y";
316                         break;
317                 case 2: axis_reg = PCI8164_AXIS_Z;
318                         axisname = "Z";
319                         break;
320                 case 3: axis_reg = PCI8164_AXIS_U;
321                         axisname = "U";
322                         break;
323                 default: axis_reg = PCI8164_AXIS_X;
324                         axisname = "X";
325         }
326
327         data[0] = inw(dev->iobase + axis_reg + PCI8164_BUF1);
328         printk("comedi: pci8164 BUF1 read -> %04X:%04X on axis %s\n", data[0], data[1], axisname);
329
330         return 2;
331 }
332
333 static int adl_pci8164_insn_write_cmd(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn, lsampl_t *data)
334 {
335         unsigned int axis, axis_reg;
336
337         char *axisname;
338
339         axis = CR_CHAN(insn->chanspec);
340
341         switch (axis)
342         {
343                 case 0: axis_reg = PCI8164_AXIS_X;
344                         axisname = "X";
345                         break;
346                 case 1: axis_reg = PCI8164_AXIS_Y;
347                         axisname = "Y";
348                         break;
349                 case 2: axis_reg = PCI8164_AXIS_Z;
350                         axisname = "Z";
351                         break;
352                 case 3: axis_reg = PCI8164_AXIS_U;
353                         axisname = "U";
354                         break;
355                 default: axis_reg = PCI8164_AXIS_X;
356                         axisname = "X";
357         }
358
359         outw(data[0], dev->iobase + axis_reg + PCI8164_CMD);
360         printk("comedi: pci8164 CMD write -> %04X:%04X on axis %s\n", data[0], data[1], axisname);
361
362         return 2;
363 }
364
365 static int adl_pci8164_insn_write_otp(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn, lsampl_t *data)
366 {
367         int axis, axis_reg;
368
369         char *axisname;
370
371         axis = CR_CHAN(insn->chanspec);
372
373         switch (axis)
374         {
375                 case 0: axis_reg = PCI8164_AXIS_X;
376                         axisname = "X";
377                         break;
378                 case 1: axis_reg = PCI8164_AXIS_Y;
379                         axisname = "Y";
380                         break;
381                 case 2: axis_reg = PCI8164_AXIS_Z;
382                         axisname = "Z";
383                         break;
384                 case 3: axis_reg = PCI8164_AXIS_U;
385                         axisname = "U";
386                         break;
387                 default: axis_reg = PCI8164_AXIS_X;
388                         axisname = "X";
389         }
390
391         outw(data[0], dev->iobase + axis_reg + PCI8164_OTP);
392         printk("comedi: pci8164 OTP write -> %04X:%04X on axis %s\n", data[0], data[1], axisname);
393
394         return 2;
395 }
396
397 static int adl_pci8164_insn_write_buf0(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn, lsampl_t *data)
398 {
399         int axis, axis_reg;
400
401         char *axisname;
402
403         axis = CR_CHAN(insn->chanspec);
404
405         switch (axis)
406         {
407                 case 0: axis_reg = PCI8164_AXIS_X;
408                         axisname = "X";
409                         break;
410                 case 1: axis_reg = PCI8164_AXIS_Y;
411                         axisname = "Y";
412                         break;
413                 case 2: axis_reg = PCI8164_AXIS_Z;
414                         axisname = "Z";
415                         break;
416                 case 3: axis_reg = PCI8164_AXIS_U;
417                         axisname = "U";
418                         break;
419                 default: axis_reg = PCI8164_AXIS_X;
420                         axisname = "X";
421         }
422
423         outw(data[0], dev->iobase + axis_reg + PCI8164_BUF0);
424         printk("comedi: pci8164 BUF0 write -> %04X:%04X on axis %s\n", data[0], data[1], axisname);
425
426         return 2;
427 }
428
429 static int adl_pci8164_insn_write_buf1(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn, lsampl_t *data)
430 {
431         int axis, axis_reg;
432
433         char *axisname;
434
435         axis = CR_CHAN(insn->chanspec);
436
437         switch (axis)
438         {
439                 case 0: axis_reg = PCI8164_AXIS_X;
440                         axisname = "X";
441                         break;
442                 case 1: axis_reg = PCI8164_AXIS_Y;
443                         axisname = "Y";
444                         break;
445                 case 2: axis_reg = PCI8164_AXIS_Z;
446                         axisname = "Z";
447                         break;
448                 case 3: axis_reg = PCI8164_AXIS_U;
449                         axisname = "U";
450                         break;
451                 default: axis_reg = PCI8164_AXIS_X;
452                         axisname = "X";
453         }
454
455         outw(data[0], dev->iobase + axis_reg + PCI8164_BUF1);
456         printk("comedi: pci8164 BUF1 write -> %04X:%04X on axis %s\n", data[0], data[1], axisname);
457
458         return 2;
459 }
460
461 COMEDI_INITCLEANUP(driver_adl_pci8164);