1a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef/*
2a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef    comedi/drivers/comedi_fc.c
3a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
4a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef    This is a place for code driver writers wish to share between
5a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef    two or more drivers.  fc is short
6a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef    for frank-common.
7a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
8a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef    Author:  Frank Mori Hess <fmhess@users.sourceforge.net>
9a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef    Copyright (C) 2002 Frank Mori Hess
10a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
11a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef    This program is free software; you can redistribute it and/or modify
12a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef    it under the terms of the GNU General Public License as published by
13a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef    the Free Software Foundation; either version 2 of the License, or
14a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef    (at your option) any later version.
15a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
16a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef    This program is distributed in the hope that it will be useful,
17a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef    but WITHOUT ANY WARRANTY; without even the implied warranty of
18a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef    GNU General Public License for more details.
20a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
21a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef    You should have received a copy of the GNU General Public License
22a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef    along with this program; if not, write to the Free Software
23a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
25a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef************************************************************************/
26a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
27a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef#include "../comedidev.h"
28a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
29a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef#include "comedi_fc.h"
30a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
3134c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic void increment_scan_progress(struct comedi_subdevice *subd,
324e85a13b4ea73aa3bb9f735d77a949393cbbad2bGreg Kroah-Hartman				    unsigned int num_bytes)
33a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef{
34d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton	struct comedi_async *async = subd->async;
35a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	unsigned int scan_length = cfc_bytes_per_scan(subd);
36a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
37a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	async->scan_progress += num_bytes;
38a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	if (async->scan_progress >= scan_length) {
39a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef		async->scan_progress %= scan_length;
40a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef		async->events |= COMEDI_CB_EOS;
41a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	}
42a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef}
43a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
44a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef/* Writes an array of data points to comedi's buffer */
450a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralunsigned int cfc_write_array_to_buffer(struct comedi_subdevice *subd,
460a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				       void *data, unsigned int num_bytes)
47a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef{
48d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton	struct comedi_async *async = subd->async;
49a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	unsigned int retval;
50a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
51a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	if (num_bytes == 0)
52a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef		return 0;
53a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
54a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	retval = comedi_buf_write_alloc(async, num_bytes);
55a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	if (retval != num_bytes) {
56d62a01d861b0d47b1ff16bdfa0f31580d5083c95Klaas van Gend		printk(KERN_WARNING "comedi: buffer overrun\n");
57a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef		async->events |= COMEDI_CB_OVERFLOW;
58a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef		return 0;
59a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	}
60a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
61a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	comedi_buf_memcpy_to(async, 0, data, num_bytes);
62a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	comedi_buf_write_free(async, num_bytes);
63a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	increment_scan_progress(subd, num_bytes);
64a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	async->events |= COMEDI_CB_BLOCK;
65a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
66a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	return num_bytes;
67a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef}
684e85a13b4ea73aa3bb9f735d77a949393cbbad2bGreg Kroah-HartmanEXPORT_SYMBOL(cfc_write_array_to_buffer);
69a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
700a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralunsigned int cfc_read_array_from_buffer(struct comedi_subdevice *subd,
710a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral					void *data, unsigned int num_bytes)
72a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef{
73d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton	struct comedi_async *async = subd->async;
74a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
75a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	if (num_bytes == 0)
76a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef		return 0;
77a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
78a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	num_bytes = comedi_buf_read_alloc(async, num_bytes);
79a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	comedi_buf_memcpy_from(async, 0, data, num_bytes);
80a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	comedi_buf_read_free(async, num_bytes);
81a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	increment_scan_progress(subd, num_bytes);
82a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	async->events |= COMEDI_CB_BLOCK;
83a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
84a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	return num_bytes;
85a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef}
864e85a13b4ea73aa3bb9f735d77a949393cbbad2bGreg Kroah-HartmanEXPORT_SYMBOL(cfc_read_array_from_buffer);
87a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
880a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralunsigned int cfc_handle_events(struct comedi_device *dev,
890a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			       struct comedi_subdevice *subd)
90a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef{
91a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	unsigned int events = subd->async->events;
92a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
93a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	if (events == 0)
94a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef		return events;
95a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
96a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	if (events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW))
97a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef		subd->cancel(dev, subd);
98a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
99a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	comedi_event(dev, subd);
100a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
101a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	return events;
102a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef}
1034e85a13b4ea73aa3bb9f735d77a949393cbbad2bGreg Kroah-HartmanEXPORT_SYMBOL(cfc_handle_events);
104a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
105a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David SchleefMODULE_AUTHOR("Frank Mori Hess <fmhess@users.sourceforge.net>");
106a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David SchleefMODULE_DESCRIPTION("Shared functions for Comedi low-level drivers");
107a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David SchleefMODULE_LICENSE("GPL");
108a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
109a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleefstatic int __init comedi_fc_init_module(void)
110a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef{
111a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	return 0;
112a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef}
1134e85a13b4ea73aa3bb9f735d77a949393cbbad2bGreg Kroah-Hartman
114a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleefstatic void __exit comedi_fc_cleanup_module(void)
115a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef{
116a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef}
117a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
118a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleefmodule_init(comedi_fc_init_module);
119a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleefmodule_exit(comedi_fc_cleanup_module);
120