4 * @brief 8254 subdevice instance.
5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
10 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
12 * This file is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
34 #include <linux/module.h>
36 #include <linux/slab.h>
37 #include <linux/spinlock.h>
39 #include <linux/types.h>
41 #include "medefines.h"
42 #include "meinternal.h"
46 #include "me8254_reg.h"
52 #define ME8254_NUMBER_CHANNELS 1 /**< One channel per counter. */
53 #define ME8254_CTR_WIDTH 16 /**< One counter has 16 bits. */
59 static int me8254_io_reset_subdevice(struct me_subdevice
*subdevice
,
60 struct file
*filep
, int flags
)
62 me8254_subdevice_t
*instance
;
64 int err
= ME_ERRNO_SUCCESS
;
66 PDEBUG("executed.\n");
68 instance
= (me8254_subdevice_t
*) subdevice
;
71 PERROR("Invalid flag specified.\n");
72 return ME_ERRNO_INVALID_FLAGS
;
77 spin_lock(&instance
->subdevice_lock
);
78 spin_lock(instance
->ctrl_reg_lock
);
79 if (instance
->ctr_idx
== 0)
80 outb(ME8254_CTRL_SC0
| ME8254_CTRL_LM
| ME8254_CTRL_M0
|
81 ME8254_CTRL_BIN
, instance
->ctrl_reg
);
82 else if (instance
->ctr_idx
== 1)
83 outb(ME8254_CTRL_SC1
| ME8254_CTRL_LM
| ME8254_CTRL_M0
|
84 ME8254_CTRL_BIN
, instance
->ctrl_reg
);
86 outb(ME8254_CTRL_SC2
| ME8254_CTRL_LM
| ME8254_CTRL_M0
|
87 ME8254_CTRL_BIN
, instance
->ctrl_reg
);
88 spin_unlock(instance
->ctrl_reg_lock
);
90 outb(0x00, instance
->val_reg
);
91 outb(0x00, instance
->val_reg
);
93 spin_lock(instance
->clk_src_reg_lock
);
94 clk_src
= inb(instance
->clk_src_reg
);
96 switch (instance
->device_id
) {
97 case PCI_DEVICE_ID_MEILHAUS_ME1400
:
98 case PCI_DEVICE_ID_MEILHAUS_ME140A
:
99 case PCI_DEVICE_ID_MEILHAUS_ME140B
:
100 case PCI_DEVICE_ID_MEILHAUS_ME14E0
:
101 case PCI_DEVICE_ID_MEILHAUS_ME14EA
:
102 case PCI_DEVICE_ID_MEILHAUS_ME14EB
:
103 if (instance
->me8254_idx
== 0) {
104 if (instance
->ctr_idx
== 0)
106 ~(ME1400AB_8254_A_0_CLK_SRC_10MHZ
|
107 ME1400AB_8254_A_0_CLK_SRC_QUARZ
);
108 else if (instance
->ctr_idx
== 1)
109 clk_src
&= ~(ME1400AB_8254_A_1_CLK_SRC_PREV
);
111 clk_src
&= ~(ME1400AB_8254_A_2_CLK_SRC_PREV
);
113 if (instance
->ctr_idx
== 0)
115 ~(ME1400AB_8254_B_0_CLK_SRC_10MHZ
|
116 ME1400AB_8254_B_0_CLK_SRC_QUARZ
);
117 else if (instance
->ctr_idx
== 1)
118 clk_src
&= ~(ME1400AB_8254_B_1_CLK_SRC_PREV
);
120 clk_src
&= ~(ME1400AB_8254_B_2_CLK_SRC_PREV
);
124 case PCI_DEVICE_ID_MEILHAUS_ME140C
:
125 case PCI_DEVICE_ID_MEILHAUS_ME140D
:
126 switch (instance
->me8254_idx
) {
132 if (instance
->ctr_idx
== 0)
133 clk_src
&= ~(ME1400CD_8254_ACE_0_CLK_SRC_MASK
);
134 else if (instance
->ctr_idx
== 1)
135 clk_src
&= ~(ME1400CD_8254_ACE_1_CLK_SRC_MASK
);
137 clk_src
&= ~(ME1400CD_8254_ACE_2_CLK_SRC_MASK
);
141 if (instance
->ctr_idx
== 0)
142 clk_src
&= ~(ME1400CD_8254_BD_0_CLK_SRC_MASK
);
143 else if (instance
->ctr_idx
== 1)
144 clk_src
&= ~(ME1400CD_8254_BD_1_CLK_SRC_MASK
);
146 clk_src
&= ~(ME1400CD_8254_BD_2_CLK_SRC_MASK
);
151 case PCI_DEVICE_ID_MEILHAUS_ME4610
:
152 case PCI_DEVICE_ID_MEILHAUS_ME4660
:
153 case PCI_DEVICE_ID_MEILHAUS_ME4660I
:
154 case PCI_DEVICE_ID_MEILHAUS_ME4660S
:
155 case PCI_DEVICE_ID_MEILHAUS_ME4660IS
:
156 case PCI_DEVICE_ID_MEILHAUS_ME4670
:
157 case PCI_DEVICE_ID_MEILHAUS_ME4670I
:
158 case PCI_DEVICE_ID_MEILHAUS_ME4670S
:
159 case PCI_DEVICE_ID_MEILHAUS_ME4670IS
:
160 case PCI_DEVICE_ID_MEILHAUS_ME4680
:
161 case PCI_DEVICE_ID_MEILHAUS_ME4680I
:
162 case PCI_DEVICE_ID_MEILHAUS_ME4680S
:
163 case PCI_DEVICE_ID_MEILHAUS_ME4680IS
:
164 case PCI_DEVICE_ID_MEILHAUS_ME8100_A
:
165 case PCI_DEVICE_ID_MEILHAUS_ME8100_B
:
167 /* No clock source register available */
171 PERROR("Invalid device type.\n");
172 err
= ME_ERRNO_INTERNAL
;
176 outb(clk_src
, instance
->clk_src_reg
);
178 spin_unlock(instance
->clk_src_reg_lock
);
179 spin_unlock(&instance
->subdevice_lock
);
186 static int me1400_ab_ref_config(me8254_subdevice_t
*instance
, int ref
)
190 spin_lock(instance
->clk_src_reg_lock
);
191 clk_src
= inb(instance
->clk_src_reg
);
194 case ME_REF_CTR_EXTERNAL
:
195 if (instance
->me8254_idx
== 0) {
196 if (instance
->ctr_idx
== 0)
197 clk_src
&= ~(ME1400AB_8254_A_0_CLK_SRC_QUARZ
);
198 else if (instance
->ctr_idx
== 1)
199 clk_src
&= ~(ME1400AB_8254_A_1_CLK_SRC_PREV
);
201 clk_src
&= ~(ME1400AB_8254_A_2_CLK_SRC_PREV
);
203 if (instance
->ctr_idx
== 0)
204 clk_src
&= ~(ME1400AB_8254_B_0_CLK_SRC_QUARZ
);
205 else if (instance
->ctr_idx
== 1)
206 clk_src
&= ~(ME1400AB_8254_B_1_CLK_SRC_PREV
);
208 clk_src
&= ~(ME1400AB_8254_B_2_CLK_SRC_PREV
);
213 case ME_REF_CTR_PREVIOUS
:
214 if (instance
->me8254_idx
== 0) {
215 if (instance
->ctr_idx
== 0) {
216 PERROR("Invalid reference.\n");
217 spin_unlock(instance
->clk_src_reg_lock
);
218 return ME_ERRNO_INVALID_SINGLE_CONFIG
;
219 } else if (instance
->ctr_idx
== 1)
220 clk_src
|= (ME1400AB_8254_A_1_CLK_SRC_PREV
);
222 clk_src
|= (ME1400AB_8254_A_2_CLK_SRC_PREV
);
224 if (instance
->ctr_idx
== 0) {
225 PERROR("Invalid reference.\n");
226 spin_unlock(instance
->clk_src_reg_lock
);
227 return ME_ERRNO_INVALID_SINGLE_CONFIG
;
228 } else if (instance
->ctr_idx
== 1)
229 clk_src
|= (ME1400AB_8254_B_1_CLK_SRC_PREV
);
231 clk_src
|= (ME1400AB_8254_B_2_CLK_SRC_PREV
);
236 case ME_REF_CTR_INTERNAL_1MHZ
:
237 if (instance
->me8254_idx
== 0) {
238 if (instance
->ctr_idx
== 0) {
239 clk_src
|= (ME1400AB_8254_A_0_CLK_SRC_QUARZ
);
240 clk_src
&= ~(ME1400AB_8254_A_0_CLK_SRC_10MHZ
);
242 PERROR("Invalid reference.\n");
243 spin_unlock(instance
->clk_src_reg_lock
);
244 return ME_ERRNO_INVALID_SINGLE_CONFIG
;
247 if (instance
->ctr_idx
== 0) {
248 clk_src
|= (ME1400AB_8254_B_0_CLK_SRC_QUARZ
);
249 clk_src
&= ~(ME1400AB_8254_B_0_CLK_SRC_10MHZ
);
251 PERROR("Invalid reference.\n");
252 spin_unlock(instance
->clk_src_reg_lock
);
253 return ME_ERRNO_INVALID_SINGLE_CONFIG
;
259 case ME_REF_CTR_INTERNAL_10MHZ
:
260 if (instance
->me8254_idx
== 0) {
261 if (instance
->ctr_idx
== 0) {
262 clk_src
|= (ME1400AB_8254_A_0_CLK_SRC_QUARZ
);
263 clk_src
|= (ME1400AB_8254_A_0_CLK_SRC_10MHZ
);
265 PERROR("Invalid reference.\n");
266 spin_unlock(instance
->clk_src_reg_lock
);
267 return ME_ERRNO_INVALID_SINGLE_CONFIG
;
270 if (instance
->ctr_idx
== 0) {
271 clk_src
|= (ME1400AB_8254_A_0_CLK_SRC_QUARZ
);
272 clk_src
|= (ME1400AB_8254_A_0_CLK_SRC_10MHZ
);
274 PERROR("Invalid reference.\n");
275 spin_unlock(instance
->clk_src_reg_lock
);
276 return ME_ERRNO_INVALID_SINGLE_CONFIG
;
283 PERROR("Invalid reference.\n");
284 spin_unlock(instance
->clk_src_reg_lock
);
285 return ME_ERRNO_INVALID_REF
;
288 outb(clk_src
, instance
->clk_src_reg
);
289 spin_unlock(instance
->clk_src_reg_lock
);
291 return ME_ERRNO_SUCCESS
;
294 static int me1400_cd_ref_config(me8254_subdevice_t
*instance
, int ref
)
298 spin_lock(instance
->clk_src_reg_lock
);
299 clk_src
= inb(instance
->clk_src_reg
);
302 case ME_REF_CTR_EXTERNAL
:
303 switch (instance
->me8254_idx
) {
309 if (instance
->ctr_idx
== 0)
310 clk_src
&= ~(ME1400CD_8254_ACE_0_CLK_SRC_MASK
);
311 else if (instance
->ctr_idx
== 1)
312 clk_src
&= ~(ME1400CD_8254_ACE_1_CLK_SRC_MASK
);
314 clk_src
&= ~(ME1400CD_8254_ACE_2_CLK_SRC_MASK
);
318 if (instance
->ctr_idx
== 0)
319 clk_src
&= ~(ME1400CD_8254_BD_0_CLK_SRC_MASK
);
320 else if (instance
->ctr_idx
== 1)
321 clk_src
&= ~(ME1400CD_8254_BD_1_CLK_SRC_MASK
);
323 clk_src
&= ~(ME1400CD_8254_BD_2_CLK_SRC_MASK
);
328 case ME_REF_CTR_PREVIOUS
:
329 switch (instance
->me8254_idx
) {
335 if (instance
->ctr_idx
== 0) {
336 clk_src
&= ~(ME1400CD_8254_ACE_0_CLK_SRC_MASK
);
337 clk_src
|= (ME1400CD_8254_ACE_0_CLK_SRC_PREV
);
338 } else if (instance
->ctr_idx
== 1) {
339 clk_src
&= ~(ME1400CD_8254_ACE_1_CLK_SRC_MASK
);
340 clk_src
|= (ME1400CD_8254_ACE_1_CLK_SRC_PREV
);
342 clk_src
&= ~(ME1400CD_8254_ACE_2_CLK_SRC_MASK
);
343 clk_src
|= (ME1400CD_8254_ACE_2_CLK_SRC_PREV
);
348 if (instance
->ctr_idx
== 0) {
349 clk_src
&= ~(ME1400CD_8254_BD_0_CLK_SRC_MASK
);
350 clk_src
|= (ME1400CD_8254_BD_0_CLK_SRC_PREV
);
351 } else if (instance
->ctr_idx
== 1) {
352 clk_src
&= ~(ME1400CD_8254_BD_1_CLK_SRC_MASK
);
353 clk_src
|= (ME1400CD_8254_BD_1_CLK_SRC_PREV
);
355 clk_src
&= ~(ME1400CD_8254_BD_2_CLK_SRC_MASK
);
356 clk_src
|= (ME1400CD_8254_BD_2_CLK_SRC_PREV
);
363 case ME_REF_CTR_INTERNAL_1MHZ
:
364 switch (instance
->me8254_idx
) {
370 if (instance
->ctr_idx
== 0) {
371 clk_src
&= ~(ME1400CD_8254_ACE_0_CLK_SRC_MASK
);
372 clk_src
|= (ME1400CD_8254_ACE_0_CLK_SRC_1MHZ
);
374 PERROR("Invalid reference.\n");
375 spin_unlock(instance
->clk_src_reg_lock
);
376 return ME_ERRNO_INVALID_REF
;
382 if (instance
->ctr_idx
== 0) {
383 clk_src
&= ~(ME1400CD_8254_BD_0_CLK_SRC_MASK
);
384 clk_src
|= (ME1400CD_8254_BD_0_CLK_SRC_1MHZ
);
386 PERROR("Invalid reference.\n");
387 spin_unlock(instance
->clk_src_reg_lock
);
388 return ME_ERRNO_INVALID_REF
;
395 case ME_REF_CTR_INTERNAL_10MHZ
:
396 switch (instance
->me8254_idx
) {
402 if (instance
->ctr_idx
== 0) {
403 clk_src
&= ~(ME1400CD_8254_ACE_0_CLK_SRC_MASK
);
404 clk_src
|= (ME1400CD_8254_ACE_0_CLK_SRC_10MHZ
);
406 PERROR("Invalid reference.\n");
407 spin_unlock(instance
->clk_src_reg_lock
);
408 return ME_ERRNO_INVALID_REF
;
413 if (instance
->ctr_idx
== 0) {
414 clk_src
&= ~(ME1400CD_8254_BD_0_CLK_SRC_MASK
);
415 clk_src
|= (ME1400CD_8254_BD_0_CLK_SRC_10MHZ
);
417 PERROR("Invalid reference.\n");
418 spin_unlock(instance
->clk_src_reg_lock
);
419 return ME_ERRNO_INVALID_REF
;
428 PERROR("Invalid reference.\n");
429 spin_unlock(instance
->clk_src_reg_lock
);
430 return ME_ERRNO_INVALID_REF
;
433 outb(clk_src
, instance
->clk_src_reg
);
434 spin_unlock(instance
->clk_src_reg_lock
);
436 return ME_ERRNO_SUCCESS
;
439 static int me4600_ref_config(me8254_subdevice_t
*instance
, int ref
)
443 case ME_REF_CTR_EXTERNAL
:
448 PERROR("Invalid reference.\n");
449 // spin_unlock(instance->clk_src_reg_lock);
450 return ME_ERRNO_INVALID_REF
;
453 return ME_ERRNO_SUCCESS
;
456 static int me8100_ref_config(me8254_subdevice_t
*instance
, int ref
)
460 case ME_REF_CTR_EXTERNAL
:
465 PERROR("Invalid reference.\n");
466 // spin_unlock(instance->clk_src_reg_lock);
467 return ME_ERRNO_INVALID_REF
;
470 return ME_ERRNO_SUCCESS
;
473 static int me8254_io_single_config(struct me_subdevice
*subdevice
,
479 int trig_type
, int trig_edge
, int flags
)
481 me8254_subdevice_t
*instance
;
484 PDEBUG("executed.\n");
487 PERROR("Invalid channel.\n");
488 return ME_ERRNO_INVALID_CHANNEL
;
491 instance
= (me8254_subdevice_t
*) subdevice
;
494 PERROR("Invalid flag specified.\n");
495 return ME_ERRNO_INVALID_FLAGS
;
500 spin_lock(&instance
->subdevice_lock
);
501 // Configure the counter modes
502 if (instance
->ctr_idx
== 0) {
503 if (single_config
== ME_SINGLE_CONFIG_CTR_8254_MODE_0
) {
504 outb(ME8254_CTRL_SC0
| ME8254_CTRL_LM
| ME8254_CTRL_M0
|
505 ME8254_CTRL_BIN
, instance
->ctrl_reg
);
506 } else if (single_config
== ME_SINGLE_CONFIG_CTR_8254_MODE_1
) {
507 outb(ME8254_CTRL_SC0
| ME8254_CTRL_LM
| ME8254_CTRL_M1
|
508 ME8254_CTRL_BIN
, instance
->ctrl_reg
);
509 } else if (single_config
== ME_SINGLE_CONFIG_CTR_8254_MODE_2
) {
510 outb(ME8254_CTRL_SC0
| ME8254_CTRL_LM
| ME8254_CTRL_M2
|
511 ME8254_CTRL_BIN
, instance
->ctrl_reg
);
512 } else if (single_config
== ME_SINGLE_CONFIG_CTR_8254_MODE_3
) {
513 outb(ME8254_CTRL_SC0
| ME8254_CTRL_LM
| ME8254_CTRL_M3
|
514 ME8254_CTRL_BIN
, instance
->ctrl_reg
);
515 } else if (single_config
== ME_SINGLE_CONFIG_CTR_8254_MODE_4
) {
516 outb(ME8254_CTRL_SC0
| ME8254_CTRL_LM
| ME8254_CTRL_M4
|
517 ME8254_CTRL_BIN
, instance
->ctrl_reg
);
518 } else if (single_config
== ME_SINGLE_CONFIG_CTR_8254_MODE_5
) {
519 outb(ME8254_CTRL_SC0
| ME8254_CTRL_LM
| ME8254_CTRL_M5
|
520 ME8254_CTRL_BIN
, instance
->ctrl_reg
);
522 PERROR("Invalid single configuration.\n");
523 spin_unlock(&instance
->subdevice_lock
);
524 return ME_ERRNO_INVALID_SINGLE_CONFIG
;
526 } else if (instance
->ctr_idx
== 1) {
527 if (single_config
== ME_SINGLE_CONFIG_CTR_8254_MODE_0
) {
528 outb(ME8254_CTRL_SC1
| ME8254_CTRL_LM
| ME8254_CTRL_M0
|
529 ME8254_CTRL_BIN
, instance
->ctrl_reg
);
530 } else if (single_config
== ME_SINGLE_CONFIG_CTR_8254_MODE_1
) {
531 outb(ME8254_CTRL_SC1
| ME8254_CTRL_LM
| ME8254_CTRL_M1
|
532 ME8254_CTRL_BIN
, instance
->ctrl_reg
);
533 } else if (single_config
== ME_SINGLE_CONFIG_CTR_8254_MODE_2
) {
534 outb(ME8254_CTRL_SC1
| ME8254_CTRL_LM
| ME8254_CTRL_M2
|
535 ME8254_CTRL_BIN
, instance
->ctrl_reg
);
536 } else if (single_config
== ME_SINGLE_CONFIG_CTR_8254_MODE_3
) {
537 outb(ME8254_CTRL_SC1
| ME8254_CTRL_LM
| ME8254_CTRL_M3
|
538 ME8254_CTRL_BIN
, instance
->ctrl_reg
);
539 } else if (single_config
== ME_SINGLE_CONFIG_CTR_8254_MODE_4
) {
540 outb(ME8254_CTRL_SC1
| ME8254_CTRL_LM
| ME8254_CTRL_M4
|
541 ME8254_CTRL_BIN
, instance
->ctrl_reg
);
542 } else if (single_config
== ME_SINGLE_CONFIG_CTR_8254_MODE_5
) {
543 outb(ME8254_CTRL_SC1
| ME8254_CTRL_LM
| ME8254_CTRL_M5
|
544 ME8254_CTRL_BIN
, instance
->ctrl_reg
);
546 PERROR("Invalid single configuration.\n");
547 spin_unlock(&instance
->subdevice_lock
);
548 return ME_ERRNO_INVALID_SINGLE_CONFIG
;
551 if (single_config
== ME_SINGLE_CONFIG_CTR_8254_MODE_0
) {
552 outb(ME8254_CTRL_SC2
| ME8254_CTRL_LM
| ME8254_CTRL_M0
|
553 ME8254_CTRL_BIN
, instance
->ctrl_reg
);
554 } else if (single_config
== ME_SINGLE_CONFIG_CTR_8254_MODE_1
) {
555 outb(ME8254_CTRL_SC2
| ME8254_CTRL_LM
| ME8254_CTRL_M1
|
556 ME8254_CTRL_BIN
, instance
->ctrl_reg
);
557 } else if (single_config
== ME_SINGLE_CONFIG_CTR_8254_MODE_2
) {
558 outb(ME8254_CTRL_SC2
| ME8254_CTRL_LM
| ME8254_CTRL_M2
|
559 ME8254_CTRL_BIN
, instance
->ctrl_reg
);
560 } else if (single_config
== ME_SINGLE_CONFIG_CTR_8254_MODE_3
) {
561 outb(ME8254_CTRL_SC2
| ME8254_CTRL_LM
| ME8254_CTRL_M3
|
562 ME8254_CTRL_BIN
, instance
->ctrl_reg
);
563 } else if (single_config
== ME_SINGLE_CONFIG_CTR_8254_MODE_4
) {
564 outb(ME8254_CTRL_SC2
| ME8254_CTRL_LM
| ME8254_CTRL_M4
|
565 ME8254_CTRL_BIN
, instance
->ctrl_reg
);
566 } else if (single_config
== ME_SINGLE_CONFIG_CTR_8254_MODE_5
) {
567 outb(ME8254_CTRL_SC2
| ME8254_CTRL_LM
| ME8254_CTRL_M5
|
568 ME8254_CTRL_BIN
, instance
->ctrl_reg
);
570 PERROR("Invalid single configuration.\n");
571 spin_unlock(&instance
->subdevice_lock
);
572 return ME_ERRNO_INVALID_SINGLE_CONFIG
;
576 switch (instance
->device_id
) {
577 case PCI_DEVICE_ID_MEILHAUS_ME1400
:
578 case PCI_DEVICE_ID_MEILHAUS_ME14E0
:
579 case PCI_DEVICE_ID_MEILHAUS_ME140A
:
580 case PCI_DEVICE_ID_MEILHAUS_ME14EA
:
581 case PCI_DEVICE_ID_MEILHAUS_ME140B
:
582 case PCI_DEVICE_ID_MEILHAUS_ME14EB
:
583 err
= me1400_ab_ref_config(instance
, ref
);
586 spin_unlock(&instance
->subdevice_lock
);
592 case PCI_DEVICE_ID_MEILHAUS_ME140C
:
593 case PCI_DEVICE_ID_MEILHAUS_ME140D
:
594 err
= me1400_cd_ref_config(instance
, ref
);
597 spin_unlock(&instance
->subdevice_lock
);
603 case PCI_DEVICE_ID_MEILHAUS_ME4610
:
604 case PCI_DEVICE_ID_MEILHAUS_ME4660
:
605 case PCI_DEVICE_ID_MEILHAUS_ME4660I
:
606 case PCI_DEVICE_ID_MEILHAUS_ME4660S
:
607 case PCI_DEVICE_ID_MEILHAUS_ME4660IS
:
608 case PCI_DEVICE_ID_MEILHAUS_ME4670
:
609 case PCI_DEVICE_ID_MEILHAUS_ME4670I
:
610 case PCI_DEVICE_ID_MEILHAUS_ME4670S
:
611 case PCI_DEVICE_ID_MEILHAUS_ME4670IS
:
612 case PCI_DEVICE_ID_MEILHAUS_ME4680
:
613 case PCI_DEVICE_ID_MEILHAUS_ME4680I
:
614 case PCI_DEVICE_ID_MEILHAUS_ME4680S
:
615 case PCI_DEVICE_ID_MEILHAUS_ME4680IS
:
616 err
= me4600_ref_config(instance
, ref
);
619 spin_unlock(&instance
->subdevice_lock
);
625 case PCI_DEVICE_ID_MEILHAUS_ME8100_A
:
626 case PCI_DEVICE_ID_MEILHAUS_ME8100_B
:
627 err
= me8100_ref_config(instance
, ref
);
630 spin_unlock(&instance
->subdevice_lock
);
637 PERROR("Invalid device type.\n");
639 spin_unlock(&instance
->subdevice_lock
);
640 // spin_unlock(instance->clk_src_reg_lock);
641 return ME_ERRNO_INVALID_SINGLE_CONFIG
;
643 spin_unlock(&instance
->subdevice_lock
);
647 return ME_ERRNO_SUCCESS
;
650 static int me8254_io_single_read(struct me_subdevice
*subdevice
,
653 int *value
, int time_out
, int flags
)
655 me8254_subdevice_t
*instance
;
659 PDEBUG("executed.\n");
662 PERROR("Invalid channel.\n");
663 return ME_ERRNO_INVALID_CHANNEL
;
666 instance
= (me8254_subdevice_t
*) subdevice
;
669 PERROR("Invalid flag specified.\n");
670 return ME_ERRNO_INVALID_FLAGS
;
675 spin_lock(&instance
->subdevice_lock
);
676 spin_lock(instance
->ctrl_reg_lock
);
677 if (instance
->ctr_idx
== 0)
678 outb(ME8254_CTRL_SC0
| ME8254_CTRL_TLO
, instance
->ctrl_reg
);
679 else if (instance
->ctr_idx
== 1)
680 outb(ME8254_CTRL_SC1
| ME8254_CTRL_TLO
, instance
->ctrl_reg
);
682 outb(ME8254_CTRL_SC2
| ME8254_CTRL_TLO
, instance
->ctrl_reg
);
684 lo_byte
= inb(instance
->val_reg
);
685 hi_byte
= inb(instance
->val_reg
);
686 spin_unlock(instance
->ctrl_reg_lock
);
688 *value
= lo_byte
| (hi_byte
<< 8);
689 spin_unlock(&instance
->subdevice_lock
);
693 return ME_ERRNO_SUCCESS
;
696 static int me8254_io_single_write(struct me_subdevice
*subdevice
,
699 int value
, int time_out
, int flags
)
701 me8254_subdevice_t
*instance
;
703 PDEBUG("executed.\n");
706 PERROR("Invalid channel.\n");
707 return ME_ERRNO_INVALID_CHANNEL
;
710 instance
= (me8254_subdevice_t
*) subdevice
;
713 PERROR("Invalid flag specified.\n");
714 return ME_ERRNO_INVALID_FLAGS
;
719 spin_lock(&instance
->subdevice_lock
);
720 outb(value
, instance
->val_reg
);
721 outb((value
>> 8), instance
->val_reg
);
722 spin_unlock(&instance
->subdevice_lock
);
726 return ME_ERRNO_SUCCESS
;
729 static int me8254_query_number_channels(struct me_subdevice
*subdevice
,
732 PDEBUG("executed.\n");
733 *number
= ME8254_NUMBER_CHANNELS
;
734 return ME_ERRNO_SUCCESS
;
737 static int me8254_query_subdevice_type(struct me_subdevice
*subdevice
,
738 int *type
, int *subtype
)
740 PDEBUG("executed.\n");
742 *subtype
= ME_SUBTYPE_CTR_8254
;
743 return ME_ERRNO_SUCCESS
;
746 static int me8254_query_subdevice_caps(struct me_subdevice
*subdevice
,
749 me8254_subdevice_t
*instance
;
750 PDEBUG("executed.\n");
751 instance
= (me8254_subdevice_t
*) subdevice
;
752 *caps
= instance
->caps
;
753 return ME_ERRNO_SUCCESS
;
756 static int me8254_query_subdevice_caps_args(struct me_subdevice
*subdevice
,
757 int cap
, int *args
, int count
)
759 PDEBUG("executed.\n");
762 PERROR("Invalid capability argument count.\n");
763 return ME_ERRNO_INVALID_CAP_ARG_COUNT
;
766 if (cap
== ME_CAP_CTR_WIDTH
) {
767 args
[0] = ME8254_CTR_WIDTH
;
769 PERROR("Invalid capability.\n");
770 return ME_ERRNO_INVALID_CAP
;
773 return ME_ERRNO_SUCCESS
;
776 static uint32_t me1400AB_get_val_reg(uint32_t reg_base
, unsigned int me8254_idx
,
777 unsigned int ctr_idx
)
779 switch (me8254_idx
) {
782 return (reg_base
+ ME1400AB_8254_A_0_VAL_REG
+ ctr_idx
);
785 return (reg_base
+ ME1400AB_8254_B_0_VAL_REG
+ ctr_idx
);
791 static uint32_t me1400AB_get_ctrl_reg(uint32_t reg_base
,
792 unsigned int me8254_idx
,
793 unsigned int ctr_idx
)
795 switch (me8254_idx
) {
797 return (reg_base
+ ME1400AB_8254_A_CTRL_REG
);
800 return (reg_base
+ ME1400AB_8254_B_CTRL_REG
);
806 static uint32_t me1400AB_get_clk_src_reg(uint32_t reg_base
,
807 unsigned int me8254_idx
,
808 unsigned int ctr_idx
)
810 switch (me8254_idx
) {
812 return (reg_base
+ ME1400AB_CLK_SRC_REG
);
815 return (reg_base
+ ME1400AB_CLK_SRC_REG
);
821 static uint32_t me1400CD_get_val_reg(uint32_t reg_base
, unsigned int me8254_idx
,
822 unsigned int ctr_idx
)
824 switch (me8254_idx
) {
826 return (reg_base
+ ME1400C_8254_A_0_VAL_REG
+ ctr_idx
);
829 return (reg_base
+ ME1400C_8254_B_0_VAL_REG
+ ctr_idx
);
832 return (reg_base
+ ME1400C_8254_C_0_VAL_REG
+ ctr_idx
);
835 return (reg_base
+ ME1400C_8254_D_0_VAL_REG
+ ctr_idx
);
838 return (reg_base
+ ME1400C_8254_E_0_VAL_REG
+ ctr_idx
);
841 return (reg_base
+ ME1400D_8254_A_0_VAL_REG
+ ctr_idx
);
844 return (reg_base
+ ME1400D_8254_B_0_VAL_REG
+ ctr_idx
);
847 return (reg_base
+ ME1400D_8254_C_0_VAL_REG
+ ctr_idx
);
850 return (reg_base
+ ME1400D_8254_D_0_VAL_REG
+ ctr_idx
);
853 return (reg_base
+ ME1400D_8254_E_0_VAL_REG
+ ctr_idx
);
859 static uint32_t me1400CD_get_ctrl_reg(uint32_t reg_base
,
860 unsigned int me8254_idx
,
861 unsigned int ctr_idx
)
863 switch (me8254_idx
) {
865 return (reg_base
+ ME1400C_8254_A_CTRL_REG
);
868 return (reg_base
+ ME1400C_8254_B_CTRL_REG
);
871 return (reg_base
+ ME1400C_8254_C_CTRL_REG
);
874 return (reg_base
+ ME1400C_8254_D_CTRL_REG
);
877 return (reg_base
+ ME1400C_8254_E_CTRL_REG
);
880 return (reg_base
+ ME1400D_8254_A_CTRL_REG
);
883 return (reg_base
+ ME1400D_8254_B_CTRL_REG
);
886 return (reg_base
+ ME1400D_8254_C_CTRL_REG
);
889 return (reg_base
+ ME1400D_8254_D_CTRL_REG
);
892 return (reg_base
+ ME1400D_8254_E_CTRL_REG
);
898 static uint32_t me1400CD_get_clk_src_reg(uint32_t reg_base
,
899 unsigned int me8254_idx
,
900 unsigned int ctr_idx
)
902 switch (me8254_idx
) {
904 return (reg_base
+ ME1400C_CLK_SRC_0_REG
);
907 return (reg_base
+ ME1400C_CLK_SRC_0_REG
);
910 return (reg_base
+ ME1400C_CLK_SRC_1_REG
);
913 return (reg_base
+ ME1400C_CLK_SRC_1_REG
);
916 return (reg_base
+ ME1400C_CLK_SRC_2_REG
);
919 return (reg_base
+ ME1400D_CLK_SRC_0_REG
);
922 return (reg_base
+ ME1400D_CLK_SRC_0_REG
);
925 return (reg_base
+ ME1400D_CLK_SRC_1_REG
);
928 return (reg_base
+ ME1400D_CLK_SRC_1_REG
);
931 return (reg_base
+ ME1400D_CLK_SRC_2_REG
);
937 static uint32_t me4600_get_val_reg(uint32_t reg_base
, unsigned int me8254_idx
,
938 unsigned int ctr_idx
)
940 return (reg_base
+ ME4600_8254_0_VAL_REG
+ ctr_idx
);
943 static uint32_t me4600_get_ctrl_reg(uint32_t reg_base
, unsigned int me8254_idx
,
944 unsigned int ctr_idx
)
946 return (reg_base
+ ME4600_8254_CTRL_REG
);
949 static uint32_t me8100_get_val_reg(uint32_t reg_base
, unsigned int me8254_idx
,
950 unsigned int ctr_idx
)
952 return (reg_base
+ ME8100_COUNTER_REG_0
+ ctr_idx
* 2);
955 static uint32_t me8100_get_ctrl_reg(uint32_t reg_base
, unsigned int me8254_idx
,
956 unsigned int ctr_idx
)
958 return (reg_base
+ ME8100_COUNTER_CTRL_REG
);
961 me8254_subdevice_t
*me8254_constructor(uint32_t device_id
,
963 unsigned int me8254_idx
,
964 unsigned int ctr_idx
,
965 spinlock_t
*ctrl_reg_lock
,
966 spinlock_t
*clk_src_reg_lock
)
968 me8254_subdevice_t
*subdevice
;
971 PDEBUG("executed.\n");
973 // Allocate memory for subdevice instance
974 subdevice
= kmalloc(sizeof(me8254_subdevice_t
), GFP_KERNEL
);
977 PERROR("Cannot get memory for 8254 instance.\n");
981 memset(subdevice
, 0, sizeof(me8254_subdevice_t
));
983 // Check if counter index is out of range
986 PERROR("Counter index is out of range.\n");
990 // Initialize subdevice base class
991 err
= me_subdevice_init(&subdevice
->base
);
994 PERROR("Cannot initialize subdevice base class instance.\n");
998 // Initialize spin locks.
999 spin_lock_init(&subdevice
->subdevice_lock
);
1000 subdevice
->ctrl_reg_lock
= ctrl_reg_lock
;
1001 subdevice
->clk_src_reg_lock
= clk_src_reg_lock
;
1003 // Save type of Meilhaus device
1004 subdevice
->device_id
= device_id
;
1007 subdevice
->me8254_idx
= me8254_idx
;
1008 subdevice
->ctr_idx
= ctr_idx
;
1010 // Do device specific initialization
1011 switch (device_id
) {
1013 case PCI_DEVICE_ID_MEILHAUS_ME140A
:
1014 case PCI_DEVICE_ID_MEILHAUS_ME14EA
:
1015 // Check if 8254 index is out of range
1016 if (me8254_idx
> 0) {
1017 PERROR("8254 index is out of range.\n");
1018 me_subdevice_deinit(&subdevice
->base
);
1023 case PCI_DEVICE_ID_MEILHAUS_ME140B
: // Fall through
1024 case PCI_DEVICE_ID_MEILHAUS_ME14EB
:
1025 // Check if 8254 index is out of range
1026 if (me8254_idx
> 1) {
1027 PERROR("8254 index is out of range.\n");
1028 me_subdevice_deinit(&subdevice
->base
);
1032 // Initialize the counters capabilities
1035 ME_CAPS_CTR_CLK_INTERNAL_1MHZ
|
1036 ME_CAPS_CTR_CLK_INTERNAL_10MHZ
|
1037 ME_CAPS_CTR_CLK_EXTERNAL
;
1040 ME_CAPS_CTR_CLK_PREVIOUS
| ME_CAPS_CTR_CLK_EXTERNAL
;
1042 // Get the counters registers
1043 subdevice
->val_reg
=
1044 me1400AB_get_val_reg(reg_base
, me8254_idx
, ctr_idx
);
1045 subdevice
->ctrl_reg
=
1046 me1400AB_get_ctrl_reg(reg_base
, me8254_idx
, ctr_idx
);
1047 subdevice
->clk_src_reg
=
1048 me1400AB_get_clk_src_reg(reg_base
, me8254_idx
, ctr_idx
);
1051 case PCI_DEVICE_ID_MEILHAUS_ME140C
:
1052 // Check if 8254 index is out of range
1053 if (me8254_idx
> 4) {
1054 PERROR("8254 index is out of range.\n");
1055 me_subdevice_deinit(&subdevice
->base
);
1060 case PCI_DEVICE_ID_MEILHAUS_ME140D
:
1061 // Check if 8254 index is out of range
1062 if (me8254_idx
> 9) {
1063 PERROR("8254 index is out of range.\n");
1064 me_subdevice_deinit(&subdevice
->base
);
1068 // Initialize the counters capabilities
1070 if (me8254_idx
== 0)
1072 ME_CAPS_CTR_CLK_PREVIOUS
|
1073 ME_CAPS_CTR_CLK_INTERNAL_1MHZ
|
1074 ME_CAPS_CTR_CLK_INTERNAL_10MHZ
|
1075 ME_CAPS_CTR_CLK_EXTERNAL
;
1078 ME_CAPS_CTR_CLK_INTERNAL_1MHZ
|
1079 ME_CAPS_CTR_CLK_INTERNAL_10MHZ
|
1080 ME_CAPS_CTR_CLK_EXTERNAL
;
1083 ME_CAPS_CTR_CLK_PREVIOUS
| ME_CAPS_CTR_CLK_EXTERNAL
;
1085 // Get the counters registers
1086 subdevice
->val_reg
=
1087 me1400CD_get_val_reg(reg_base
, me8254_idx
, ctr_idx
);
1088 subdevice
->ctrl_reg
=
1089 me1400CD_get_ctrl_reg(reg_base
, me8254_idx
, ctr_idx
);
1090 subdevice
->clk_src_reg
=
1091 me1400CD_get_clk_src_reg(reg_base
, me8254_idx
, ctr_idx
);
1094 case PCI_DEVICE_ID_MEILHAUS_ME4610
:
1095 case PCI_DEVICE_ID_MEILHAUS_ME4660
:
1096 case PCI_DEVICE_ID_MEILHAUS_ME4660I
:
1097 case PCI_DEVICE_ID_MEILHAUS_ME4660S
:
1098 case PCI_DEVICE_ID_MEILHAUS_ME4660IS
:
1099 case PCI_DEVICE_ID_MEILHAUS_ME4670
:
1100 case PCI_DEVICE_ID_MEILHAUS_ME4670I
:
1101 case PCI_DEVICE_ID_MEILHAUS_ME4670S
:
1102 case PCI_DEVICE_ID_MEILHAUS_ME4670IS
:
1103 case PCI_DEVICE_ID_MEILHAUS_ME4680
:
1104 case PCI_DEVICE_ID_MEILHAUS_ME4680I
:
1105 case PCI_DEVICE_ID_MEILHAUS_ME4680S
:
1106 case PCI_DEVICE_ID_MEILHAUS_ME4680IS
:
1107 // Check if 8254 index is out of range
1108 if (me8254_idx
> 0) {
1109 PERROR("8254 index is out of range.\n");
1110 me_subdevice_deinit(&subdevice
->base
);
1114 // Initialize the counters capabilities
1115 subdevice
->caps
= ME_CAPS_CTR_CLK_EXTERNAL
;
1117 // Get the counters registers
1118 subdevice
->val_reg
=
1119 me4600_get_val_reg(reg_base
, me8254_idx
, ctr_idx
);
1120 subdevice
->ctrl_reg
=
1121 me4600_get_ctrl_reg(reg_base
, me8254_idx
, ctr_idx
);
1122 subdevice
->clk_src_reg
= 0; // Not used
1125 case PCI_DEVICE_ID_MEILHAUS_ME8100_A
:
1126 case PCI_DEVICE_ID_MEILHAUS_ME8100_B
:
1127 // Check if 8254 index is out of range
1128 if (me8254_idx
> 0) {
1129 PERROR("8254 index is out of range.\n");
1130 me_subdevice_deinit(&subdevice
->base
);
1134 // Initialize the counters capabilities
1135 subdevice
->caps
= ME_CAPS_CTR_CLK_EXTERNAL
;
1137 // Get the counters registers
1138 subdevice
->val_reg
=
1139 me8100_get_val_reg(reg_base
, me8254_idx
, ctr_idx
);
1140 subdevice
->ctrl_reg
=
1141 me8100_get_ctrl_reg(reg_base
, me8254_idx
, ctr_idx
);
1142 subdevice
->clk_src_reg
= 0; // Not used
1145 case PCI_DEVICE_ID_MEILHAUS_ME4650
:
1146 case PCI_DEVICE_ID_MEILHAUS_ME1400
:
1147 case PCI_DEVICE_ID_MEILHAUS_ME14E0
:
1148 PERROR("No 8254 subdevices available for subdevice device.\n");
1149 me_subdevice_deinit(&subdevice
->base
);
1154 PERROR("Unknown device type.\n");
1155 me_subdevice_deinit(&subdevice
->base
);
1160 // Overload subdevice base class methods.
1161 subdevice
->base
.me_subdevice_io_reset_subdevice
=
1162 me8254_io_reset_subdevice
;
1163 subdevice
->base
.me_subdevice_io_single_config
= me8254_io_single_config
;
1164 subdevice
->base
.me_subdevice_io_single_read
= me8254_io_single_read
;
1165 subdevice
->base
.me_subdevice_io_single_write
= me8254_io_single_write
;
1166 subdevice
->base
.me_subdevice_query_number_channels
=
1167 me8254_query_number_channels
;
1168 subdevice
->base
.me_subdevice_query_subdevice_type
=
1169 me8254_query_subdevice_type
;
1170 subdevice
->base
.me_subdevice_query_subdevice_caps
=
1171 me8254_query_subdevice_caps
;
1172 subdevice
->base
.me_subdevice_query_subdevice_caps_args
=
1173 me8254_query_subdevice_caps_args
;