4 * @brief Meilhaus ME-4000 analog output subdevice class.
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.
28 # define _ME4600_AO_H_
30 # include <linux/version.h>
31 # include "mesubdevice.h"
32 # include "mecirc_buf.h"
41 # endif //_CBUFF_32b_t
44 # define ME4600_AO_MAX_SUBDEVICES 4
45 # define ME4600_AO_FIFO_COUNT 4096
47 # define ME4600_AO_BASE_FREQUENCY 33000000LL
49 # define ME4600_AO_MIN_ACQ_TICKS 0LL
50 # define ME4600_AO_MAX_ACQ_TICKS 0LL
52 # define ME4600_AO_MIN_CHAN_TICKS 66LL
53 # define ME4600_AO_MAX_CHAN_TICKS 0xFFFFFFFFLL
55 # define ME4600_AO_MIN_RANGE -10000000
56 # define ME4600_AO_MAX_RANGE 9999694
58 # define ME4600_AO_MAX_DATA 0xFFFF
61 # define ME4600_AO_CIRC_BUF_SIZE_ORDER 8 // 2^n PAGES =>> Maximum value of 1MB for Synapse
63 # define ME4600_AO_CIRC_BUF_SIZE_ORDER 5 // 2^n PAGES =>> 128KB
65 # define ME4600_AO_CIRC_BUF_SIZE PAGE_SIZE<<ME4600_AO_CIRC_BUF_SIZE_ORDER // Buffer size in bytes.
68 # define ME4600_AO_CIRC_BUF_COUNT ((ME4600_AO_CIRC_BUF_SIZE) / sizeof(uint32_t)) // Size in values
70 # define ME4600_AO_CIRC_BUF_COUNT ((ME4600_AO_CIRC_BUF_SIZE) / sizeof(uint16_t)) // Size in values
73 # define ME4600_AO_CONTINOUS 0x0
74 # define ME4600_AO_WRAP_MODE 0x1
75 # define ME4600_AO_HW_MODE 0x2
77 # define ME4600_AO_HW_WRAP_MODE (ME4600_AO_WRAP_MODE | ME4600_AO_HW_MODE)
78 # define ME4600_AO_SW_WRAP_MODE ME4600_AO_WRAP_MODE
80 # define ME4600_AO_INF_STOP_MODE 0x0
81 # define ME4600_AO_ACQ_STOP_MODE 0x1
82 # define ME4600_AO_SCAN_STOP_MODE 0x2
84 # ifdef BOSCH //SPECIAL BUILD FOR BOSCH
86 /* Bits for flags attribute. */
87 # define ME4600_AO_FLAGS_BROKEN_PIPE 0x1
88 # define ME4600_AO_FLAGS_SW_WRAP_MODE_0 0x2
89 # define ME4600_AO_FLAGS_SW_WRAP_MODE_1 0x4
90 # define ME4600_AO_FLAGS_SW_WRAP_MODE_MASK (ME4600_AO_FLAGS_SW_WRAP_MODE_0 | ME4600_AO_FLAGS_SW_WRAP_MODE_1)
92 # define ME4600_AO_FLAGS_SW_WRAP_MODE_NONE 0x0
93 # define ME4600_AO_FLAGS_SW_WRAP_MODE_INF 0x2
94 # define ME4600_AO_FLAGS_SW_WRAP_MODE_FIN 0x4
97 * @brief The ME-4000 analog output subdevice class.
99 typedef struct me4600_ao_subdevice {
101 me_subdevice_t base; /**< The subdevice base class. */
104 spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
105 spinlock_t *preload_reg_lock; /**< Spin lock to protect #preload_reg from concurrent access. */
106 uint32_t *preload_flags;
108 unsigned int irq; /**< The interrupt request number assigned by the PCI BIOS. */
109 me_circ_buf_t circ_buf; /**< Circular buffer holding measurment data. */
110 wait_queue_head_t wait_queue; /**< Wait queue to put on tasks waiting for data to arrive. */
112 int single_value; /**< Mirror of the value written in single mode. */
114 int volatile flags; /**< Flags used for storing SW wraparound setup and error signalling from ISR. */
115 unsigned int wrap_count; /**< The user defined wraparound cycle count. */
116 unsigned int wrap_remaining; /**< The wraparound cycle down counter used by a running conversion. */
117 unsigned int ao_idx; /**< The index of this analog output on this device. */
118 int fifo; /**< If set this device has a FIFO. */
120 int bosch_fw; /**< If set the bosch firmware is in PROM. */
128 uint32_t irq_status_reg;
129 uint32_t preload_reg;
131 } me4600_ao_subdevice_t;
134 * @brief The constructor to generate a ME-4000 analog output subdevice instance for BOSCH project.
136 * @param reg_base The register base address of the device as returned by the PCI BIOS.
137 * @param ctrl_reg_lock Pointer to spin lock protecting the control register from concurrent access.
138 * @param preload_flags Pointer to spin lock protecting the hold&trigger register from concurrent access.
139 * @param ao_idx Subdevice number.
140 * @param fifo Flag set if subdevice has hardware FIFO.
141 * @param irq IRQ number.
143 * @return Pointer to new instance on success.\n
146 me4600_ao_subdevice_t *me4600_ao_constructor(uint32_t reg_base,
147 spinlock_t * preload_reg_lock,
148 uint32_t * preload_flags,
149 int ao_idx, int fifo, int irq);
153 //ME4600_AO_FLAGS_BROKEN_PIPE is OBSOLETE => Now problems are reported in status.
155 typedef enum ME4600_AO_STATUS {
157 ao_status_single_configured,
158 ao_status_single_run_wait,
159 ao_status_single_run,
160 ao_status_single_end_wait,
161 ao_status_single_end,
162 ao_status_stream_configured,
163 ao_status_stream_run_wait,
164 ao_status_stream_run,
165 ao_status_stream_end_wait,
166 ao_status_stream_end,
167 ao_status_stream_fifo_error,
168 ao_status_stream_buffer_error,
169 ao_status_stream_error,
173 typedef struct me4600_ao_timeout {
174 unsigned long start_time;
176 } me4600_ao_timeout_t;
179 * @brief The ME-4600 analog output subdevice class.
181 typedef struct me4600_ao_subdevice {
183 me_subdevice_t base; /**< The subdevice base class. */
184 unsigned int ao_idx; /**< The index of this analog output on this device. */
187 spinlock_t subdevice_lock; /**< Spin lock to protect the subdevice from concurrent access. */
188 spinlock_t *preload_reg_lock; /**< Spin lock to protect preload_reg from concurrent access. */
190 uint32_t *preload_flags;
192 /* Hardware feautres */
193 unsigned int irq; /**< The interrupt request number assigned by the PCI BIOS. */
194 int fifo; /**< If set this device has a FIFO. */
195 int bitpattern; /**< If set this device use bitpattern. */
197 int single_value; /**< Mirror of the output value in single mode. */
198 int single_value_in_fifo; /**< Mirror of the value written in single mode. */
199 uint32_t ctrl_trg; /**< Mirror of the trigger settings. */
201 volatile int mode; /**< Flags used for storing SW wraparound setup*/
202 int stop_mode; /**< The user defined stop condition flag. */
203 unsigned int start_mode;
204 unsigned int stop_count; /**< The user defined dates presentation end count. */
205 unsigned int stop_data_count; /**< The stop presentation count. */
206 unsigned int data_count; /**< The real presentation count. */
207 unsigned int preloaded_count; /**< The next data addres in buffer. <= for wraparound mode. */
208 int hardware_stop_delay; /**< The time that stop can take. This is only to not show hardware bug to user. */
210 volatile enum ME4600_AO_STATUS status; /**< The current stream status flag. */
211 me4600_ao_timeout_t timeout; /**< The timeout for start in blocking and non-blocking mode. */
213 /* Registers *//**< All registers are 32 bits long. */
214 unsigned long ctrl_reg;
215 unsigned long status_reg;
216 unsigned long fifo_reg;
217 unsigned long single_reg;
218 unsigned long timer_reg;
219 unsigned long irq_status_reg;
220 unsigned long preload_reg;
221 unsigned long reg_base;
223 /* Software buffer */
224 me_circ_buf_t circ_buf; /**< Circular buffer holding measurment data. 32 bit long */
225 wait_queue_head_t wait_queue; /**< Wait queue to put on tasks waiting for data to arrive. */
227 struct workqueue_struct *me4600_workqueue;
228 struct delayed_work ao_control_task;
230 volatile int ao_control_task_flag; /**< Flag controling reexecuting of control task */
232 } me4600_ao_subdevice_t;
235 * @brief The constructor to generate a ME-4600 analog output subdevice instance.
237 * @param reg_base The register base address of the device as returned by the PCI BIOS.
238 * @param ctrl_reg_lock Pointer to spin lock protecting the control register from concurrent access.
239 * @param preload_flags Pointer to spin lock protecting the hold&trigger register from concurrent access.
240 * @param ao_idx Subdevice number.
241 * @param fifo Flag set if subdevice has hardware FIFO.
242 * @param irq IRQ number.
243 * @param me4600_wq Queue for asynchronous task (1 queue for all subdevice on 1 board).
245 * @return Pointer to new instance on success.\n
248 me4600_ao_subdevice_t *me4600_ao_constructor(uint32_t reg_base,
249 spinlock_t * preload_reg_lock,
250 uint32_t * preload_flags,
254 struct workqueue_struct
259 #endif // ~_ME4600_AO_H_