• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * @file me1600_ao.h
3  *
4  * @brief Meilhaus ME-1600 analog output subdevice class.
5  * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6  * @author Guenter Gebhardt
7  */
8 
9 /*
10  * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
11  *
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.
16  *
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.
21  *
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.
25  */
26 
27 #ifndef _ME1600_AO_H_
28 #define _ME1600_AO_H_
29 
30 # include <linux/version.h>
31 # include "mesubdevice.h"
32 
33 # ifdef __KERNEL__
34 
35 #  define ME1600_MAX_RANGES	2	/**< Specifies the maximum number of ranges in me1600_ao_subdevice_t::u_ranges und me1600_ao_subdevice_t::i_ranges. */
36 
37 /**
38  * @brief Defines a entry in the range table.
39  */
40 typedef struct me1600_ao_range_entry {
41 	int32_t min;
42 	int32_t max;
43 } me1600_ao_range_entry_t;
44 
45 typedef struct me1600_ao_timeout {
46 	unsigned long start_time;
47 	unsigned long delay;
48 } me1600_ao_timeout_t;
49 
50 typedef struct me1600_ao_shadow {
51 	int count;
52 	unsigned long *registry;
53 	uint16_t *shadow;
54 	uint16_t *mirror;
55 	uint16_t synchronous;									/**< Synchronization list. */
56 	uint16_t trigger;										/**< Synchronization flag. */
57 } me1600_ao_shadow_t;
58 
59 typedef enum ME1600_AO_STATUS {
60 	ao_status_none = 0,
61 	ao_status_single_configured,
62 	ao_status_single_run,
63 	ao_status_single_end,
64 	ao_status_last
65 } ME1600_AO_STATUS;
66 
67 /**
68  * @brief The ME-1600 analog output subdevice class.
69  */
70 typedef struct me1600_ao_subdevice {
71 	/* Inheritance */
72 	me_subdevice_t base;									/**< The subdevice base class. */
73 
74 	/* Attributes */
75 	int ao_idx;												/**< The index of the analog output subdevice on the device. */
76 
77 	spinlock_t subdevice_lock;								/**< Spin lock to protect the subdevice from concurrent access. */
78 	spinlock_t *config_regs_lock;							/**< Spin lock to protect configuration registers from concurrent access. */
79 
80 	int u_ranges_count;										/**< The number of voltage ranges available on this subdevice. */
81 	me1600_ao_range_entry_t u_ranges[ME1600_MAX_RANGES];	/**< Array holding the voltage ranges on this subdevice. */
82 	int i_ranges_count;										/**< The number of current ranges available on this subdevice. */
83 	me1600_ao_range_entry_t i_ranges[ME1600_MAX_RANGES];	/**< Array holding the current ranges on this subdevice. */
84 
85 	/* Registers */
86 	unsigned long uni_bi_reg;								/**< Register for switching between unipoar and bipolar output mode. */
87 	unsigned long i_range_reg;								/**< Register for switching between ranges. */
88 	unsigned long sim_output_reg;							/**< Register used in order to update all channels simultaneously. */
89 	unsigned long current_on_reg;							/**< Register enabling current output on the fourth subdevice. */
90 #   ifdef PDEBUG_REG
91 	unsigned long reg_base;
92 #   endif
93 
94 	ME1600_AO_STATUS status;
95 	me1600_ao_shadow_t *ao_regs_shadows;					/**< Addresses and shadows of output's registers. */
96 	spinlock_t *ao_shadows_lock;							/**< Protects the shadow's struct. */
97 	int mode;												/**< Mode in witch output should works. */
98 	wait_queue_head_t wait_queue;							/**< Wait queue to put on tasks waiting for data to arrive. */
99 	me1600_ao_timeout_t timeout;							/**< The timeout for start in blocking and non-blocking mode. */
100 	struct workqueue_struct *me1600_workqueue;
101 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
102 	struct work_struct ao_control_task;
103 #else
104 	struct delayed_work ao_control_task;
105 #endif
106 
107 	volatile int ao_control_task_flag;						/**< Flag controling reexecuting of control task */
108 } me1600_ao_subdevice_t;
109 
110 /**
111  * @brief The constructor to generate a subdevice template instance.
112  *
113  * @param reg_base The register base address of the device as returned by the PCI BIOS.
114  * @param ao_idx The index of the analog output subdevice on the device.
115  * @param current Flag indicating that analog output with #ao_idx of 3 is capable of current output.
116  * @param config_regs_lock Pointer to spin lock protecting the configuration registers and from concurrent access.
117  *
118  * @return Pointer to new instance on success.\n
119  * NULL on error.
120  */
121 me1600_ao_subdevice_t *me1600_ao_constructor(uint32_t reg_base,
122 					     unsigned int ao_idx,
123 					     int curr,
124 					     spinlock_t * config_regs_lock,
125 					     spinlock_t * ao_shadows_lock,
126 					     me1600_ao_shadow_t *
127 					     ao_regs_shadows,
128 					     struct workqueue_struct
129 					     *me1600_wq);
130 
131 # endif	//__KERNEL__
132 #endif //_ME1600_AO_H_
133