1 From be8e89087ec2d2c8a1ad1e3db64bf4efdfc3c298 Mon Sep 17 00:00:00 2001
2 From: Ian Abbott <abbotti@mev.co.uk>
3 Date: Mon, 19 Jan 2015 14:47:27 +0000
4 Subject: staging: comedi: cb_pcidas64: fix incorrect AI range code handling
6 From: Ian Abbott <abbotti@mev.co.uk>
8 commit be8e89087ec2d2c8a1ad1e3db64bf4efdfc3c298 upstream.
10 The hardware range code values and list of valid ranges for the AI
11 subdevice is incorrect for several supported boards. The hardware range
12 code values for all boards except PCI-DAS4020/12 is determined by
13 calling `ai_range_bits_6xxx()` based on the maximum voltage of the range
14 and whether it is bipolar or unipolar, however it only returns the
15 correct hardware range code for the PCI-DAS60xx boards. For
16 PCI-DAS6402/16 (and /12) it returns the wrong code for the unipolar
17 ranges. For PCI-DAS64/Mx/16 it returns the wrong code for all the
18 ranges and the comedi range table is incorrect.
20 Change `ai_range_bits_6xxx()` to use a look-up table pointed to by new
21 member `ai_range_codes` of `struct pcidas64_board` to map the comedi
22 range table indices to the hardware range codes. Use a new comedi range
23 table for the PCI-DAS64/Mx/16 boards (and the commented out variants).
25 Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
26 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
29 drivers/staging/comedi/drivers/cb_pcidas64.c | 124 ++++++++++++++++-----------
30 1 file changed, 76 insertions(+), 48 deletions(-)
32 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c
33 +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c
34 @@ -439,6 +439,29 @@ static const struct comedi_lrange ai_ran
38 +static const uint8_t ai_range_code_64xx[8] = {
39 + 0x0, 0x1, 0x2, 0x3, /* bipolar 10, 5, 2,5, 1.25 */
40 + 0x8, 0x9, 0xa, 0xb /* unipolar 10, 5, 2.5, 1.25 */
43 +/* analog input ranges for 64-Mx boards */
44 +static const struct comedi_lrange ai_ranges_64_mx = {
56 +static const uint8_t ai_range_code_64_mx[7] = {
57 + 0x0, 0x1, 0x2, 0x3, /* bipolar 5, 2.5, 1.25, 0.625 */
58 + 0x9, 0xa, 0xb /* unipolar 5, 2.5, 1.25 */
61 /* analog input ranges for 60xx boards */
62 static const struct comedi_lrange ai_ranges_60xx = {
64 @@ -449,6 +472,10 @@ static const struct comedi_lrange ai_ran
68 +static const uint8_t ai_range_code_60xx[4] = {
69 + 0x0, 0x1, 0x4, 0x7 /* bipolar 10, 5, 0.5, 0.05 */
72 /* analog input ranges for 6030, etc boards */
73 static const struct comedi_lrange ai_ranges_6030 = {
75 @@ -469,6 +496,11 @@ static const struct comedi_lrange ai_ran
79 +static const uint8_t ai_range_code_6030[14] = {
80 + 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, /* bip 10, 5, 2, 1, 0.5, 0.2, 0.1 */
81 + 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf /* uni 10, 5, 2, 1, 0.5, 0.2, 0.1 */
84 /* analog input ranges for 6052, etc boards */
85 static const struct comedi_lrange ai_ranges_6052 = {
87 @@ -490,6 +522,11 @@ static const struct comedi_lrange ai_ran
91 +static const uint8_t ai_range_code_6052[15] = {
92 + 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, /* bipolar 10 ... 0.05 */
93 + 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf /* unipolar 10 ... 0.1 */
96 /* analog input ranges for 4020 board */
97 static const struct comedi_lrange ai_ranges_4020 = {
99 @@ -593,6 +630,7 @@ struct pcidas64_board {
100 int ai_bits; /* analog input resolution */
101 int ai_speed; /* fastest conversion period in ns */
102 const struct comedi_lrange *ai_range_table;
103 + const uint8_t *ai_range_code;
104 int ao_nchan; /* number of analog out channels */
105 int ao_bits; /* analog output resolution */
106 int ao_scan_speed; /* analog output scan speed */
107 @@ -651,6 +689,7 @@ static const struct pcidas64_board pcida
108 .ao_scan_speed = 10000,
109 .layout = LAYOUT_64XX,
110 .ai_range_table = &ai_ranges_64xx,
111 + .ai_range_code = ai_range_code_64xx,
112 .ao_range_table = &ao_ranges_64xx,
113 .ao_range_code = ao_range_code_64xx,
114 .ai_fifo = &ai_fifo_64xx,
115 @@ -666,6 +705,7 @@ static const struct pcidas64_board pcida
116 .ao_scan_speed = 10000,
117 .layout = LAYOUT_64XX,
118 .ai_range_table = &ai_ranges_64xx,
119 + .ai_range_code = ai_range_code_64xx,
120 .ao_range_table = &ao_ranges_64xx,
121 .ao_range_code = ao_range_code_64xx,
122 .ai_fifo = &ai_fifo_64xx,
123 @@ -680,7 +720,8 @@ static const struct pcidas64_board pcida
125 .ao_scan_speed = 10000,
126 .layout = LAYOUT_64XX,
127 - .ai_range_table = &ai_ranges_64xx,
128 + .ai_range_table = &ai_ranges_64_mx,
129 + .ai_range_code = ai_range_code_64_mx,
130 .ao_range_table = &ao_ranges_64xx,
131 .ao_range_code = ao_range_code_64xx,
132 .ai_fifo = &ai_fifo_64xx,
133 @@ -695,7 +736,8 @@ static const struct pcidas64_board pcida
135 .ao_scan_speed = 10000,
136 .layout = LAYOUT_64XX,
137 - .ai_range_table = &ai_ranges_64xx,
138 + .ai_range_table = &ai_ranges_64_mx,
139 + .ai_range_code = ai_range_code_64_mx,
140 .ao_range_table = &ao_ranges_64xx,
141 .ao_range_code = ao_range_code_64xx,
142 .ai_fifo = &ai_fifo_64xx,
143 @@ -710,7 +752,8 @@ static const struct pcidas64_board pcida
145 .ao_scan_speed = 10000,
146 .layout = LAYOUT_64XX,
147 - .ai_range_table = &ai_ranges_64xx,
148 + .ai_range_table = &ai_ranges_64_mx,
149 + .ai_range_code = ai_range_code_64_mx,
150 .ao_range_table = &ao_ranges_64xx,
151 .ao_range_code = ao_range_code_64xx,
152 .ai_fifo = &ai_fifo_64xx,
153 @@ -725,6 +768,7 @@ static const struct pcidas64_board pcida
155 .layout = LAYOUT_60XX,
156 .ai_range_table = &ai_ranges_60xx,
157 + .ai_range_code = ai_range_code_60xx,
158 .ao_range_table = &range_bipolar10,
159 .ao_range_code = ao_range_code_60xx,
160 .ai_fifo = &ai_fifo_60xx,
161 @@ -740,6 +784,7 @@ static const struct pcidas64_board pcida
162 .ao_scan_speed = 100000,
163 .layout = LAYOUT_60XX,
164 .ai_range_table = &ai_ranges_60xx,
165 + .ai_range_code = ai_range_code_60xx,
166 .ao_range_table = &range_bipolar10,
167 .ao_range_code = ao_range_code_60xx,
168 .ai_fifo = &ai_fifo_60xx,
169 @@ -754,6 +799,7 @@ static const struct pcidas64_board pcida
170 .ao_scan_speed = 100000,
171 .layout = LAYOUT_60XX,
172 .ai_range_table = &ai_ranges_60xx,
173 + .ai_range_code = ai_range_code_60xx,
174 .ao_range_table = &range_bipolar10,
175 .ao_range_code = ao_range_code_60xx,
176 .ai_fifo = &ai_fifo_60xx,
177 @@ -769,6 +815,7 @@ static const struct pcidas64_board pcida
178 .ao_scan_speed = 100000,
179 .layout = LAYOUT_60XX,
180 .ai_range_table = &ai_ranges_60xx,
181 + .ai_range_code = ai_range_code_60xx,
182 .ao_range_table = &range_bipolar10,
183 .ao_range_code = ao_range_code_60xx,
184 .ai_fifo = &ai_fifo_60xx,
185 @@ -784,6 +831,7 @@ static const struct pcidas64_board pcida
186 .ao_scan_speed = 10000,
187 .layout = LAYOUT_60XX,
188 .ai_range_table = &ai_ranges_6030,
189 + .ai_range_code = ai_range_code_6030,
190 .ao_range_table = &ao_ranges_6030,
191 .ao_range_code = ao_range_code_6030,
192 .ai_fifo = &ai_fifo_60xx,
193 @@ -799,6 +847,7 @@ static const struct pcidas64_board pcida
194 .ao_scan_speed = 10000,
195 .layout = LAYOUT_60XX,
196 .ai_range_table = &ai_ranges_6030,
197 + .ai_range_code = ai_range_code_6030,
198 .ao_range_table = &ao_ranges_6030,
199 .ao_range_code = ao_range_code_6030,
200 .ai_fifo = &ai_fifo_60xx,
201 @@ -812,6 +861,7 @@ static const struct pcidas64_board pcida
203 .layout = LAYOUT_60XX,
204 .ai_range_table = &ai_ranges_6030,
205 + .ai_range_code = ai_range_code_6030,
206 .ai_fifo = &ai_fifo_60xx,
209 @@ -823,6 +873,7 @@ static const struct pcidas64_board pcida
211 .layout = LAYOUT_60XX,
212 .ai_range_table = &ai_ranges_6030,
213 + .ai_range_code = ai_range_code_6030,
214 .ai_fifo = &ai_fifo_60xx,
217 @@ -835,6 +886,7 @@ static const struct pcidas64_board pcida
219 .layout = LAYOUT_60XX,
220 .ai_range_table = &ai_ranges_60xx,
221 + .ai_range_code = ai_range_code_60xx,
222 .ai_fifo = &ai_fifo_60xx,
225 @@ -848,6 +900,7 @@ static const struct pcidas64_board pcida
226 .ao_scan_speed = 100000,
227 .layout = LAYOUT_60XX,
228 .ai_range_table = &ai_ranges_60xx,
229 + .ai_range_code = ai_range_code_60xx,
230 .ao_range_table = &range_bipolar10,
231 .ao_range_code = ao_range_code_60xx,
232 .ai_fifo = &ai_fifo_60xx,
233 @@ -863,6 +916,7 @@ static const struct pcidas64_board pcida
234 .ao_scan_speed = 100000,
235 .layout = LAYOUT_60XX,
236 .ai_range_table = &ai_ranges_60xx,
237 + .ai_range_code = ai_range_code_60xx,
238 .ao_range_table = &range_bipolar10,
239 .ao_range_code = ao_range_code_60xx,
240 .ai_fifo = &ai_fifo_60xx,
241 @@ -878,6 +932,7 @@ static const struct pcidas64_board pcida
242 .ao_scan_speed = 1000,
243 .layout = LAYOUT_60XX,
244 .ai_range_table = &ai_ranges_6052,
245 + .ai_range_code = ai_range_code_6052,
246 .ao_range_table = &ao_ranges_6030,
247 .ao_range_code = ao_range_code_6030,
248 .ai_fifo = &ai_fifo_60xx,
249 @@ -893,6 +948,7 @@ static const struct pcidas64_board pcida
250 .ao_scan_speed = 3333,
251 .layout = LAYOUT_60XX,
252 .ai_range_table = &ai_ranges_6052,
253 + .ai_range_code = ai_range_code_6052,
254 .ao_range_table = &ao_ranges_6030,
255 .ao_range_code = ao_range_code_6030,
256 .ai_fifo = &ai_fifo_60xx,
257 @@ -908,6 +964,7 @@ static const struct pcidas64_board pcida
258 .ao_scan_speed = 1000,
259 .layout = LAYOUT_60XX,
260 .ai_range_table = &ai_ranges_6052,
261 + .ai_range_code = ai_range_code_6052,
262 .ao_range_table = &ao_ranges_6030,
263 .ao_range_code = ao_range_code_6030,
264 .ai_fifo = &ai_fifo_60xx,
265 @@ -923,6 +980,7 @@ static const struct pcidas64_board pcida
266 .ao_scan_speed = 1000,
267 .layout = LAYOUT_60XX,
268 .ai_range_table = &ai_ranges_6052,
269 + .ai_range_code = ai_range_code_6052,
270 .ao_range_table = &ao_ranges_6030,
271 .ao_range_code = ao_range_code_6030,
272 .ai_fifo = &ai_fifo_60xx,
273 @@ -957,6 +1015,7 @@ static const struct pcidas64_board pcida
274 .ao_scan_speed = 10000,
275 .layout = LAYOUT_64XX,
276 .ai_range_table = &ai_ranges_64xx,
277 + .ai_range_code = ai_range_code_64xx,
278 .ai_fifo = ai_fifo_64xx,
281 @@ -968,7 +1027,8 @@ static const struct pcidas64_board pcida
283 .ao_scan_speed = 10000,
284 .layout = LAYOUT_64XX,
285 - .ai_range_table = &ai_ranges_64xx,
286 + .ai_range_table = &ai_ranges_64_mx,
287 + .ai_range_code = ai_range_code_64_mx,
288 .ai_fifo = ai_fifo_64xx,
291 @@ -980,7 +1040,8 @@ static const struct pcidas64_board pcida
293 .ao_scan_speed = 10000,
294 .layout = LAYOUT_64XX,
295 - .ai_range_table = &ai_ranges_64xx,
296 + .ai_range_table = &ai_ranges_64_mx,
297 + .ai_range_code = ai_range_code_64_mx,
298 .ai_fifo = ai_fifo_64xx,
301 @@ -992,7 +1053,8 @@ static const struct pcidas64_board pcida
303 .ao_scan_speed = 10000,
304 .layout = LAYOUT_64XX,
305 - .ai_range_table = &ai_ranges_64xx,
306 + .ai_range_table = &ai_ranges_64_mx,
307 + .ai_range_code = ai_range_code_64_mx,
308 .ai_fifo = ai_fifo_64xx,
311 @@ -1004,7 +1066,8 @@ static const struct pcidas64_board pcida
313 .ao_scan_speed = 10000,
314 .layout = LAYOUT_64XX,
315 - .ai_range_table = &ai_ranges_64xx,
316 + .ai_range_table = &ai_ranges_64_mx,
317 + .ai_range_code = ai_range_code_64_mx,
318 .ai_fifo = ai_fifo_64xx,
321 @@ -1016,7 +1079,8 @@ static const struct pcidas64_board pcida
323 .ao_scan_speed = 10000,
324 .layout = LAYOUT_64XX,
325 - .ai_range_table = &ai_ranges_64xx,
326 + .ai_range_table = &ai_ranges_64_mx,
327 + .ai_range_code = ai_range_code_64_mx,
328 .ai_fifo = ai_fifo_64xx,
331 @@ -1028,7 +1092,8 @@ static const struct pcidas64_board pcida
333 .ao_scan_speed = 10000,
334 .layout = LAYOUT_64XX,
335 - .ai_range_table = &ai_ranges_64xx,
336 + .ai_range_table = &ai_ranges_64_mx,
337 + .ai_range_code = ai_range_code_64_mx,
338 .ai_fifo = ai_fifo_64xx,
341 @@ -1115,45 +1180,8 @@ static unsigned int ai_range_bits_6xxx(c
342 unsigned int range_index)
344 const struct pcidas64_board *thisboard = dev->board_ptr;
345 - const struct comedi_krange *range =
346 - &thisboard->ai_range_table->range[range_index];
347 - unsigned int bits = 0;
349 - switch (range->max) {
378 - dev_err(dev->class_dev, "bug! in %s\n", __func__);
381 - if (range->min == 0)
385 + return thisboard->ai_range_code[range_index] << 8;
388 static unsigned int hw_revision(const struct comedi_device *dev,