12f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann/*
2cbc717919e39f113dec4b48173a069b9e66bd1e3H Hartley Sweeten * ke_counter.c
3cbc717919e39f113dec4b48173a069b9e66bd1e3H Hartley Sweeten * Comedi driver for Kolter-Electronic PCI Counter 1 Card
4cbc717919e39f113dec4b48173a069b9e66bd1e3H Hartley Sweeten *
5cbc717919e39f113dec4b48173a069b9e66bd1e3H Hartley Sweeten * COMEDI - Linux Control and Measurement Device Interface
6cbc717919e39f113dec4b48173a069b9e66bd1e3H Hartley Sweeten * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
7cbc717919e39f113dec4b48173a069b9e66bd1e3H Hartley Sweeten *
8cbc717919e39f113dec4b48173a069b9e66bd1e3H Hartley Sweeten * This program is free software; you can redistribute it and/or modify
9cbc717919e39f113dec4b48173a069b9e66bd1e3H Hartley Sweeten * it under the terms of the GNU General Public License as published by
10cbc717919e39f113dec4b48173a069b9e66bd1e3H Hartley Sweeten * the Free Software Foundation; either version 2 of the License, or
11cbc717919e39f113dec4b48173a069b9e66bd1e3H Hartley Sweeten * (at your option) any later version.
12cbc717919e39f113dec4b48173a069b9e66bd1e3H Hartley Sweeten *
13cbc717919e39f113dec4b48173a069b9e66bd1e3H Hartley Sweeten * This program is distributed in the hope that it will be useful,
14cbc717919e39f113dec4b48173a069b9e66bd1e3H Hartley Sweeten * but WITHOUT ANY WARRANTY; without even the implied warranty of
15cbc717919e39f113dec4b48173a069b9e66bd1e3H Hartley Sweeten * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16cbc717919e39f113dec4b48173a069b9e66bd1e3H Hartley Sweeten * GNU General Public License for more details.
17cbc717919e39f113dec4b48173a069b9e66bd1e3H Hartley Sweeten */
182f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann
192f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann/*
20cbc717919e39f113dec4b48173a069b9e66bd1e3H Hartley Sweeten * Driver: ke_counter
21cbc717919e39f113dec4b48173a069b9e66bd1e3H Hartley Sweeten * Description: Driver for Kolter Electronic Counter Card
22cbc717919e39f113dec4b48173a069b9e66bd1e3H Hartley Sweeten * Devices: (Kolter Electronic) PCI Counter Card [ke_counter]
23cbc717919e39f113dec4b48173a069b9e66bd1e3H Hartley Sweeten * Author: Michael Hillmann
24cbc717919e39f113dec4b48173a069b9e66bd1e3H Hartley Sweeten * Updated: Mon, 14 Apr 2008 15:42:42 +0100
25cbc717919e39f113dec4b48173a069b9e66bd1e3H Hartley Sweeten * Status: tested
26cbc717919e39f113dec4b48173a069b9e66bd1e3H Hartley Sweeten *
27cbc717919e39f113dec4b48173a069b9e66bd1e3H Hartley Sweeten * Configuration Options: not applicable, uses PCI auto config
28cbc717919e39f113dec4b48173a069b9e66bd1e3H Hartley Sweeten */
292f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann
30ce157f8032bbd46d9427034c335b0afd751da25dH Hartley Sweeten#include <linux/module.h>
3133782dd5edf8db3cdb7c81a3523bf743dd0209b7H Hartley Sweeten#include <linux/pci.h>
3233782dd5edf8db3cdb7c81a3523bf743dd0209b7H Hartley Sweeten
332f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann#include "../comedidev.h"
342f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann
354761fb4e4a97a512983e5cff422ef64e0c164454H Hartley Sweeten/*
364761fb4e4a97a512983e5cff422ef64e0c164454H Hartley Sweeten * PCI BAR 0 Register I/O map
374761fb4e4a97a512983e5cff422ef64e0c164454H Hartley Sweeten */
384761fb4e4a97a512983e5cff422ef64e0c164454H Hartley Sweeten#define KE_RESET_REG(x)			(0x00 + ((x) * 0x20))
394761fb4e4a97a512983e5cff422ef64e0c164454H Hartley Sweeten#define KE_LATCH_REG(x)			(0x00 + ((x) * 0x20))
404761fb4e4a97a512983e5cff422ef64e0c164454H Hartley Sweeten#define KE_LSB_REG(x)			(0x04 + ((x) * 0x20))
414761fb4e4a97a512983e5cff422ef64e0c164454H Hartley Sweeten#define KE_MID_REG(x)			(0x08 + ((x) * 0x20))
424761fb4e4a97a512983e5cff422ef64e0c164454H Hartley Sweeten#define KE_MSB_REG(x)			(0x0c + ((x) * 0x20))
434761fb4e4a97a512983e5cff422ef64e0c164454H Hartley Sweeten#define KE_SIGN_REG(x)			(0x10 + ((x) * 0x20))
444761fb4e4a97a512983e5cff422ef64e0c164454H Hartley Sweeten#define KE_OSC_SEL_REG			0xf8
454761fb4e4a97a512983e5cff422ef64e0c164454H Hartley Sweeten#define KE_OSC_SEL_EXT			(1 << 0)
464761fb4e4a97a512983e5cff422ef64e0c164454H Hartley Sweeten#define KE_OSC_SEL_4MHZ			(2 << 0)
474761fb4e4a97a512983e5cff422ef64e0c164454H Hartley Sweeten#define KE_OSC_SEL_20MHZ		(3 << 0)
484761fb4e4a97a512983e5cff422ef64e0c164454H Hartley Sweeten#define KE_DO_REG			0xfc
494761fb4e4a97a512983e5cff422ef64e0c164454H Hartley Sweeten
5089d9dcd0a42a4978e203974fc7b0bf307c05b8a7H Hartley Sweetenstatic int ke_counter_insn_write(struct comedi_device *dev,
5189d9dcd0a42a4978e203974fc7b0bf307c05b8a7H Hartley Sweeten				 struct comedi_subdevice *s,
5289d9dcd0a42a4978e203974fc7b0bf307c05b8a7H Hartley Sweeten				 struct comedi_insn *insn,
5389d9dcd0a42a4978e203974fc7b0bf307c05b8a7H Hartley Sweeten				 unsigned int *data)
542f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann{
5599a1b98b32211713d8e544e9737a5fa20b73dce3H Hartley Sweeten	unsigned int chan = CR_CHAN(insn->chanspec);
5699a1b98b32211713d8e544e9737a5fa20b73dce3H Hartley Sweeten	unsigned int val;
5799a1b98b32211713d8e544e9737a5fa20b73dce3H Hartley Sweeten	int i;
582f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann
5999a1b98b32211713d8e544e9737a5fa20b73dce3H Hartley Sweeten	for (i = 0; i < insn->n; i++) {
6099a1b98b32211713d8e544e9737a5fa20b73dce3H Hartley Sweeten		val = data[0];
612f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann
6299a1b98b32211713d8e544e9737a5fa20b73dce3H Hartley Sweeten		/* Order matters */
6399a1b98b32211713d8e544e9737a5fa20b73dce3H Hartley Sweeten		outb((val >> 24) & 0xff, dev->iobase + KE_SIGN_REG(chan));
6499a1b98b32211713d8e544e9737a5fa20b73dce3H Hartley Sweeten		outb((val >> 16) & 0xff, dev->iobase + KE_MSB_REG(chan));
6599a1b98b32211713d8e544e9737a5fa20b73dce3H Hartley Sweeten		outb((val >> 8) & 0xff, dev->iobase + KE_MID_REG(chan));
6699a1b98b32211713d8e544e9737a5fa20b73dce3H Hartley Sweeten		outb((val >> 0) & 0xff, dev->iobase + KE_LSB_REG(chan));
6799a1b98b32211713d8e544e9737a5fa20b73dce3H Hartley Sweeten	}
6899a1b98b32211713d8e544e9737a5fa20b73dce3H Hartley Sweeten
6999a1b98b32211713d8e544e9737a5fa20b73dce3H Hartley Sweeten	return insn->n;
702f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann}
712f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann
7289d9dcd0a42a4978e203974fc7b0bf307c05b8a7H Hartley Sweetenstatic int ke_counter_insn_read(struct comedi_device *dev,
7389d9dcd0a42a4978e203974fc7b0bf307c05b8a7H Hartley Sweeten				struct comedi_subdevice *s,
7489d9dcd0a42a4978e203974fc7b0bf307c05b8a7H Hartley Sweeten				struct comedi_insn *insn,
7589d9dcd0a42a4978e203974fc7b0bf307c05b8a7H Hartley Sweeten				unsigned int *data)
762f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann{
77d250972f93d3d73134bd8a251fed86e9e9d0dab5H Hartley Sweeten	unsigned int chan = CR_CHAN(insn->chanspec);
78d250972f93d3d73134bd8a251fed86e9e9d0dab5H Hartley Sweeten	unsigned int val;
79d250972f93d3d73134bd8a251fed86e9e9d0dab5H Hartley Sweeten	int i;
802f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann
81d250972f93d3d73134bd8a251fed86e9e9d0dab5H Hartley Sweeten	for (i = 0; i < insn->n; i++) {
82d250972f93d3d73134bd8a251fed86e9e9d0dab5H Hartley Sweeten		/* Order matters */
83d250972f93d3d73134bd8a251fed86e9e9d0dab5H Hartley Sweeten		inb(dev->iobase + KE_LATCH_REG(chan));
842f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann
85d250972f93d3d73134bd8a251fed86e9e9d0dab5H Hartley Sweeten		val = inb(dev->iobase + KE_LSB_REG(chan));
86d250972f93d3d73134bd8a251fed86e9e9d0dab5H Hartley Sweeten		val |= (inb(dev->iobase + KE_MID_REG(chan)) << 8);
87d250972f93d3d73134bd8a251fed86e9e9d0dab5H Hartley Sweeten		val |= (inb(dev->iobase + KE_MSB_REG(chan)) << 16);
88d250972f93d3d73134bd8a251fed86e9e9d0dab5H Hartley Sweeten		val |= (inb(dev->iobase + KE_SIGN_REG(chan)) << 24);
892f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann
90d250972f93d3d73134bd8a251fed86e9e9d0dab5H Hartley Sweeten		data[i] = val;
91d250972f93d3d73134bd8a251fed86e9e9d0dab5H Hartley Sweeten	}
922f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann
93d250972f93d3d73134bd8a251fed86e9e9d0dab5H Hartley Sweeten	return insn->n;
942f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann}
952f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann
96f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweetenstatic void ke_counter_reset(struct comedi_device *dev)
97f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten{
98f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten	unsigned int chan;
99f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten
100f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten	for (chan = 0; chan < 3; chan++)
101f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten		outb(0, dev->iobase + KE_RESET_REG(chan));
102f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten}
103f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten
104f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweetenstatic int ke_counter_insn_config(struct comedi_device *dev,
105f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten				  struct comedi_subdevice *s,
106f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten				  struct comedi_insn *insn,
107f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten				  unsigned int *data)
108f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten{
1095fc391853ea2a9070ae4161e21783e64c1b79f6cH Hartley Sweeten	unsigned char src;
1105fc391853ea2a9070ae4161e21783e64c1b79f6cH Hartley Sweeten
111f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten	switch (data[0]) {
112f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten	case INSN_CONFIG_SET_CLOCK_SRC:
113f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten		switch (data[1]) {
1145fc391853ea2a9070ae4161e21783e64c1b79f6cH Hartley Sweeten		case KE_CLK_20MHZ:	/* default */
1155fc391853ea2a9070ae4161e21783e64c1b79f6cH Hartley Sweeten			src = KE_OSC_SEL_20MHZ;
1165fc391853ea2a9070ae4161e21783e64c1b79f6cH Hartley Sweeten			break;
1175fc391853ea2a9070ae4161e21783e64c1b79f6cH Hartley Sweeten		case KE_CLK_4MHZ:	/* option */
1185fc391853ea2a9070ae4161e21783e64c1b79f6cH Hartley Sweeten			src = KE_OSC_SEL_4MHZ;
1195fc391853ea2a9070ae4161e21783e64c1b79f6cH Hartley Sweeten			break;
1205fc391853ea2a9070ae4161e21783e64c1b79f6cH Hartley Sweeten		case KE_CLK_EXT:	/* Pin 21 on D-sub */
1215fc391853ea2a9070ae4161e21783e64c1b79f6cH Hartley Sweeten			src = KE_OSC_SEL_EXT;
122f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten			break;
123f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten		default:
124f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten			return -EINVAL;
125f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten		}
1265fc391853ea2a9070ae4161e21783e64c1b79f6cH Hartley Sweeten		outb(src, dev->iobase + KE_OSC_SEL_REG);
127f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten		break;
128f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten	case INSN_CONFIG_GET_CLOCK_SRC:
1295fc391853ea2a9070ae4161e21783e64c1b79f6cH Hartley Sweeten		src = inb(dev->iobase + KE_OSC_SEL_REG);
1305fc391853ea2a9070ae4161e21783e64c1b79f6cH Hartley Sweeten		switch (src) {
1315fc391853ea2a9070ae4161e21783e64c1b79f6cH Hartley Sweeten		case KE_OSC_SEL_20MHZ:
1325fc391853ea2a9070ae4161e21783e64c1b79f6cH Hartley Sweeten			data[1] = KE_CLK_20MHZ;
1335fc391853ea2a9070ae4161e21783e64c1b79f6cH Hartley Sweeten			data[2] = 50;	/* 50ns */
134f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten			break;
135f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten		case KE_OSC_SEL_4MHZ:
1365fc391853ea2a9070ae4161e21783e64c1b79f6cH Hartley Sweeten			data[1] = KE_CLK_4MHZ;
137f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten			data[2] = 250;	/* 250ns */
138f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten			break;
1395fc391853ea2a9070ae4161e21783e64c1b79f6cH Hartley Sweeten		case KE_OSC_SEL_EXT:
1405fc391853ea2a9070ae4161e21783e64c1b79f6cH Hartley Sweeten			data[1] = KE_CLK_EXT;
1415fc391853ea2a9070ae4161e21783e64c1b79f6cH Hartley Sweeten			data[2] = 0;	/* Unknown */
142f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten			break;
143f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten		default:
1445fc391853ea2a9070ae4161e21783e64c1b79f6cH Hartley Sweeten			return -EINVAL;
145f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten		}
146f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten		break;
147f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten	case INSN_CONFIG_RESET:
148f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten		ke_counter_reset(dev);
149f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten		break;
150f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten	default:
151f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten		return -EINVAL;
152f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten	}
153f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten
154f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten	return insn->n;
155f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten}
156f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten
157661b9dbbc32021ddba5a291ef3ccd86686c35373H Hartley Sweetenstatic int ke_counter_do_insn_bits(struct comedi_device *dev,
158661b9dbbc32021ddba5a291ef3ccd86686c35373H Hartley Sweeten				   struct comedi_subdevice *s,
159661b9dbbc32021ddba5a291ef3ccd86686c35373H Hartley Sweeten				   struct comedi_insn *insn,
160661b9dbbc32021ddba5a291ef3ccd86686c35373H Hartley Sweeten				   unsigned int *data)
161661b9dbbc32021ddba5a291ef3ccd86686c35373H Hartley Sweeten{
162661b9dbbc32021ddba5a291ef3ccd86686c35373H Hartley Sweeten	if (comedi_dio_update_state(s, data))
163661b9dbbc32021ddba5a291ef3ccd86686c35373H Hartley Sweeten		outb(s->state, dev->iobase + KE_DO_REG);
164661b9dbbc32021ddba5a291ef3ccd86686c35373H Hartley Sweeten
165661b9dbbc32021ddba5a291ef3ccd86686c35373H Hartley Sweeten	data[1] = s->state;
166661b9dbbc32021ddba5a291ef3ccd86686c35373H Hartley Sweeten
167661b9dbbc32021ddba5a291ef3ccd86686c35373H Hartley Sweeten	return insn->n;
168661b9dbbc32021ddba5a291ef3ccd86686c35373H Hartley Sweeten}
169661b9dbbc32021ddba5a291ef3ccd86686c35373H Hartley Sweeten
1707556dc373153f0fb7c069159eb815949148c6cf2H Hartley Sweetenstatic int ke_counter_auto_attach(struct comedi_device *dev,
1717556dc373153f0fb7c069159eb815949148c6cf2H Hartley Sweeten				  unsigned long context_unused)
172bd8a9bc167483acf21dc291a5860b4d66853e391H Hartley Sweeten{
173750af5e568d060ec6994cdcb4e86cdddfcd473c0Ian Abbott	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
17430c4d3b862aa97c52a180c458f471e21a2e4db23H Hartley Sweeten	struct comedi_subdevice *s;
1755afbfa638d52ac844459bca55170f354b109b4dcH Hartley Sweeten	int ret;
176bd8a9bc167483acf21dc291a5860b4d66853e391H Hartley Sweeten
177818f569fe930c5b8a05d1a44ece3c63c99c13c88H Hartley Sweeten	ret = comedi_pci_enable(dev);
1785afbfa638d52ac844459bca55170f354b109b4dcH Hartley Sweeten	if (ret)
1795afbfa638d52ac844459bca55170f354b109b4dcH Hartley Sweeten		return ret;
1805afbfa638d52ac844459bca55170f354b109b4dcH Hartley Sweeten	dev->iobase = pci_resource_start(pcidev, 0);
1812f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann
182661b9dbbc32021ddba5a291ef3ccd86686c35373H Hartley Sweeten	ret = comedi_alloc_subdevices(dev, 2);
1835afbfa638d52ac844459bca55170f354b109b4dcH Hartley Sweeten	if (ret)
1845afbfa638d52ac844459bca55170f354b109b4dcH Hartley Sweeten		return ret;
1852f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann
186bce27067e50e799fdada532d440d087eec6a571cH Hartley Sweeten	s = &dev->subdevices[0];
18789d9dcd0a42a4978e203974fc7b0bf307c05b8a7H Hartley Sweeten	s->type		= COMEDI_SUBD_COUNTER;
18889d9dcd0a42a4978e203974fc7b0bf307c05b8a7H Hartley Sweeten	s->subdev_flags	= SDF_READABLE;
18989d9dcd0a42a4978e203974fc7b0bf307c05b8a7H Hartley Sweeten	s->n_chan	= 3;
19099a1b98b32211713d8e544e9737a5fa20b73dce3H Hartley Sweeten	s->maxdata	= 0x01ffffff;
19189d9dcd0a42a4978e203974fc7b0bf307c05b8a7H Hartley Sweeten	s->range_table	= &range_unknown;
19289d9dcd0a42a4978e203974fc7b0bf307c05b8a7H Hartley Sweeten	s->insn_read	= ke_counter_insn_read;
19389d9dcd0a42a4978e203974fc7b0bf307c05b8a7H Hartley Sweeten	s->insn_write	= ke_counter_insn_write;
194f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten	s->insn_config	= ke_counter_insn_config;
1952f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann
196661b9dbbc32021ddba5a291ef3ccd86686c35373H Hartley Sweeten	s = &dev->subdevices[1];
197661b9dbbc32021ddba5a291ef3ccd86686c35373H Hartley Sweeten	s->type		= COMEDI_SUBD_DO;
198661b9dbbc32021ddba5a291ef3ccd86686c35373H Hartley Sweeten	s->subdev_flags	= SDF_WRITABLE;
199661b9dbbc32021ddba5a291ef3ccd86686c35373H Hartley Sweeten	s->n_chan	= 3;
200661b9dbbc32021ddba5a291ef3ccd86686c35373H Hartley Sweeten	s->maxdata	= 1;
201661b9dbbc32021ddba5a291ef3ccd86686c35373H Hartley Sweeten	s->range_table	= &range_digital;
202661b9dbbc32021ddba5a291ef3ccd86686c35373H Hartley Sweeten	s->insn_bits	= ke_counter_do_insn_bits;
203661b9dbbc32021ddba5a291ef3ccd86686c35373H Hartley Sweeten
2044761fb4e4a97a512983e5cff422ef64e0c164454H Hartley Sweeten	outb(KE_OSC_SEL_20MHZ, dev->iobase + KE_OSC_SEL_REG);
2052f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann
206f40c283a170a2c817b4eb3616adb3f86b4577f49H Hartley Sweeten	ke_counter_reset(dev);
2072f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann
2082f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann	return 0;
2092f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann}
2102f82613d3a7ef447be4ce656f757fc1ea101a4f1Michael Hillmann
21175e6301baa78b2dff00e2cc3051301c32618acd7H Hartley Sweetenstatic struct comedi_driver ke_counter_driver = {
21275e6301baa78b2dff00e2cc3051301c32618acd7H Hartley Sweeten	.driver_name	= "ke_counter",
213236788fcf0ecead56090d7d061f51974bdfed4a0H Hartley Sweeten	.module		= THIS_MODULE,
2147556dc373153f0fb7c069159eb815949148c6cf2H Hartley Sweeten	.auto_attach	= ke_counter_auto_attach,
215aac307f9dd5ce1fe651140a036ab4b0a0571b54aH Hartley Sweeten	.detach		= comedi_pci_detach,
216236788fcf0ecead56090d7d061f51974bdfed4a0H Hartley Sweeten};
217236788fcf0ecead56090d7d061f51974bdfed4a0H Hartley Sweeten
218a690b7e535f2f97a3a05ee570715abeb60a8910fBill Pembertonstatic int ke_counter_pci_probe(struct pci_dev *dev,
219b8f4ac237e382accd4b30c75043939f7ed9e79a6H Hartley Sweeten				const struct pci_device_id *id)
220236788fcf0ecead56090d7d061f51974bdfed4a0H Hartley Sweeten{
221b8f4ac237e382accd4b30c75043939f7ed9e79a6H Hartley Sweeten	return comedi_pci_auto_config(dev, &ke_counter_driver,
222b8f4ac237e382accd4b30c75043939f7ed9e79a6H Hartley Sweeten				      id->driver_data);
223236788fcf0ecead56090d7d061f51974bdfed4a0H Hartley Sweeten}
224236788fcf0ecead56090d7d061f51974bdfed4a0H Hartley Sweeten
22541e043fcfa2236bb2c4a8335eb09f4c8cee224b3Jingoo Hanstatic const struct pci_device_id ke_counter_pci_table[] = {
2268fff5ac61d0e937bfb5bf3d142a4d42f94dc1bf0H Hartley Sweeten	{ PCI_DEVICE(PCI_VENDOR_ID_KOLTER, 0x0014) },
227236788fcf0ecead56090d7d061f51974bdfed4a0H Hartley Sweeten	{ 0 }
228236788fcf0ecead56090d7d061f51974bdfed4a0H Hartley Sweeten};
22975e6301baa78b2dff00e2cc3051301c32618acd7H Hartley SweetenMODULE_DEVICE_TABLE(pci, ke_counter_pci_table);
230236788fcf0ecead56090d7d061f51974bdfed4a0H Hartley Sweeten
23175e6301baa78b2dff00e2cc3051301c32618acd7H Hartley Sweetenstatic struct pci_driver ke_counter_pci_driver = {
23275e6301baa78b2dff00e2cc3051301c32618acd7H Hartley Sweeten	.name		= "ke_counter",
23375e6301baa78b2dff00e2cc3051301c32618acd7H Hartley Sweeten	.id_table	= ke_counter_pci_table,
23475e6301baa78b2dff00e2cc3051301c32618acd7H Hartley Sweeten	.probe		= ke_counter_pci_probe,
2359901a4d75d007686e8f6473189cafc4b216b7449Peter Huewe	.remove		= comedi_pci_auto_unconfig,
236236788fcf0ecead56090d7d061f51974bdfed4a0H Hartley Sweeten};
23775e6301baa78b2dff00e2cc3051301c32618acd7H Hartley Sweetenmodule_comedi_pci_driver(ke_counter_driver, ke_counter_pci_driver);
238236788fcf0ecead56090d7d061f51974bdfed4a0H Hartley Sweeten
23990f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_AUTHOR("Comedi http://www.comedi.org");
240ba835c1615b58a66848f79e3210f070f7d476c42H Hartley SweetenMODULE_DESCRIPTION("Comedi driver for Kolter Electronic Counter Card");
24190f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_LICENSE("GPL");
242