Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
das08_cs.c
Go to the documentation of this file.
1 /*
2  comedi/drivers/das08_cs.c
3  DAS08 driver
4 
5  COMEDI - Linux Control and Measurement Device Interface
6  Copyright (C) 2000 David A. Schleef <[email protected]>
7  Copyright (C) 2001,2002,2003 Frank Mori Hess <[email protected]>
8 
9  This program is free software; you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation; either version 2 of the License, or
12  (at your option) any later version.
13 
14  This program is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program; if not, write to the Free Software
21  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 
23  PCMCIA support code for this driver is adapted from the dummy_cs.c
24  driver of the Linux PCMCIA Card Services package.
25 
26  The initial developer of the original code is David A. Hinds
27  <[email protected]>. Portions created by David A. Hinds
28  are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
29 
30 *****************************************************************
31 
32 */
33 /*
34 Driver: das08_cs
35 Description: DAS-08 PCMCIA boards
36 Author: Warren Jasper, ds, Frank Hess
37 Devices: [ComputerBoards] PCM-DAS08 (pcm-das08)
38 Status: works
39 
40 This is the PCMCIA-specific support split off from the
41 das08 driver.
42 
43 Options (for pcm-das08):
44  NONE
45 
46 Command support does not exist, but could be added for this board.
47 */
48 
49 #include "../comedidev.h"
50 
51 #include <linux/delay.h>
52 #include <linux/pci.h>
53 #include <linux/slab.h>
54 
55 #include "das08.h"
56 
57 /* pcmcia includes */
58 #include <pcmcia/cistpl.h>
59 #include <pcmcia/ds.h>
60 
61 static const struct das08_board_struct das08_cs_boards[] = {
62  {
63  .name = "pcm-das08",
64  .id = 0x0, /* XXX */
65  .bustype = pcmcia,
66  .ai_nbits = 12,
67  .ai_pg = das08_bipolar5,
68  .ai_encoding = das08_pcm_encode12,
69  .di_nchan = 3,
70  .do_nchan = 3,
71  .iosize = 16,
72  },
73  /* duplicate so driver name can be used also */
74  {
75  .name = "das08_cs",
76  .id = 0x0, /* XXX */
77  .bustype = pcmcia,
78  .ai_nbits = 12,
79  .ai_pg = das08_bipolar5,
80  .ai_encoding = das08_pcm_encode12,
81  .di_nchan = 3,
82  .do_nchan = 3,
83  .iosize = 16,
84  },
85 };
86 
87 static struct pcmcia_device *cur_dev;
88 
89 static int das08_cs_attach(struct comedi_device *dev,
90  struct comedi_devconfig *it)
91 {
92  const struct das08_board_struct *thisboard = comedi_board(dev);
93  int ret;
94  unsigned long iobase;
95  struct pcmcia_device *link = cur_dev; /* XXX hack */
96 
97  ret = alloc_private(dev, sizeof(struct das08_private_struct));
98  if (ret < 0)
99  return ret;
100 
101  dev_info(dev->class_dev, "das08_cs: attach\n");
102  /* deal with a pci board */
103 
104  if (thisboard->bustype == pcmcia) {
105  if (link == NULL) {
106  dev_err(dev->class_dev, "no pcmcia cards found\n");
107  return -EIO;
108  }
109  iobase = link->resource[0]->start;
110  } else {
111  dev_err(dev->class_dev,
112  "bug! board does not have PCMCIA bustype\n");
113  return -EINVAL;
114  }
115 
116  return das08_common_attach(dev, iobase);
117 }
118 
119 static struct comedi_driver driver_das08_cs = {
120  .driver_name = "das08_cs",
121  .module = THIS_MODULE,
122  .attach = das08_cs_attach,
123  .detach = das08_common_detach,
124  .board_name = &das08_cs_boards[0].name,
125  .num_names = ARRAY_SIZE(das08_cs_boards),
126  .offset = sizeof(struct das08_board_struct),
127 };
128 
129 static int das08_pcmcia_config_loop(struct pcmcia_device *p_dev,
130  void *priv_data)
131 {
132  if (p_dev->config_index == 0)
133  return -EINVAL;
134 
135  return pcmcia_request_io(p_dev);
136 }
137 
138 static int das08_pcmcia_attach(struct pcmcia_device *link)
139 {
140  int ret;
141 
142  link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
143 
144  ret = pcmcia_loop_config(link, das08_pcmcia_config_loop, NULL);
145  if (ret)
146  goto failed;
147 
148  if (!link->irq)
149  goto failed;
150 
151  ret = pcmcia_enable_device(link);
152  if (ret)
153  goto failed;
154 
155  cur_dev = link;
156  return 0;
157 
158 failed:
159  pcmcia_disable_device(link);
160  return ret;
161 }
162 
163 static void das08_pcmcia_detach(struct pcmcia_device *link)
164 {
165  pcmcia_disable_device(link);
166  cur_dev = NULL;
167 }
168 
169 static const struct pcmcia_device_id das08_cs_id_table[] = {
170  PCMCIA_DEVICE_MANF_CARD(0x01c5, 0x4001),
171  PCMCIA_DEVICE_NULL
172 };
173 MODULE_DEVICE_TABLE(pcmcia, das08_cs_id_table);
174 
175 static struct pcmcia_driver das08_cs_driver = {
176  .name = "pcm-das08",
177  .owner = THIS_MODULE,
178  .probe = das08_pcmcia_attach,
179  .remove = das08_pcmcia_detach,
180  .id_table = das08_cs_id_table,
181 };
182 
183 static int __init das08_cs_init_module(void)
184 {
185  int ret;
186 
187  ret = comedi_driver_register(&driver_das08_cs);
188  if (ret < 0)
189  return ret;
190 
191  ret = pcmcia_register_driver(&das08_cs_driver);
192  if (ret < 0) {
193  comedi_driver_unregister(&driver_das08_cs);
194  return ret;
195  }
196 
197  return 0;
198 
199 }
200 module_init(das08_cs_init_module);
201 
202 static void __exit das08_cs_exit_module(void)
203 {
204  pcmcia_unregister_driver(&das08_cs_driver);
205  comedi_driver_unregister(&driver_das08_cs);
206 }
207 module_exit(das08_cs_exit_module);
208 
209 MODULE_AUTHOR("David A. Schleef <[email protected]>, "
210  "Frank Mori Hess <[email protected]>");
211 MODULE_DESCRIPTION("Comedi driver for ComputerBoards DAS-08 PCMCIA boards");
212 MODULE_LICENSE("GPL");