comedi_fc.c revision a9f23e00c17567cc4b7ce50cd07226f7bfb70da6
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
31a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleefstatic void increment_scan_progress(comedi_subdevice * subd,
32a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	unsigned int num_bytes)
33a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef{
34a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	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 */
45a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleefunsigned int cfc_write_array_to_buffer(comedi_subdevice * subd, void *data,
46a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	unsigned int num_bytes)
47a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef{
48a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	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) {
56a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef		rt_printk("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}
68a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
69a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleefunsigned int cfc_read_array_from_buffer(comedi_subdevice * subd, void *data,
70a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	unsigned int num_bytes)
71a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef{
72a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	comedi_async *async = subd->async;
73a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
74a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	if (num_bytes == 0)
75a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef		return 0;
76a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
77a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	num_bytes = comedi_buf_read_alloc(async, num_bytes);
78a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	comedi_buf_memcpy_from(async, 0, data, num_bytes);
79a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	comedi_buf_read_free(async, num_bytes);
80a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	increment_scan_progress(subd, num_bytes);
81a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	async->events |= COMEDI_CB_BLOCK;
82a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
83a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	return num_bytes;
84a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef}
85a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
86a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleefunsigned int cfc_handle_events(comedi_device * dev, comedi_subdevice * subd)
87a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef{
88a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	unsigned int events = subd->async->events;
89a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
90a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	if (events == 0)
91a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef		return events;
92a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
93a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	if (events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW))
94a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef		subd->cancel(dev, subd);
95a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
96a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	comedi_event(dev, subd);
97a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
98a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	return events;
99a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef}
100a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
101a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David SchleefMODULE_AUTHOR("Frank Mori Hess <fmhess@users.sourceforge.net>");
102a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David SchleefMODULE_DESCRIPTION("Shared functions for Comedi low-level drivers");
103a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David SchleefMODULE_LICENSE("GPL");
104a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
105a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleefstatic int __init comedi_fc_init_module(void)
106a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef{
107a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef	return 0;
108a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef}
109a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleefstatic void __exit comedi_fc_cleanup_module(void)
110a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef{
111a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef}
112a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
113a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleefmodule_init(comedi_fc_init_module);
114a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleefmodule_exit(comedi_fc_cleanup_module);
115a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David Schleef
116a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David SchleefEXPORT_SYMBOL(cfc_write_array_to_buffer);
117a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David SchleefEXPORT_SYMBOL(cfc_read_array_from_buffer);
118a9f23e00c17567cc4b7ce50cd07226f7bfb70da6David SchleefEXPORT_SYMBOL(cfc_handle_events);
119