Staging: meilhaus: unsigned won't get negative after subtraction
[safe/jmp/linux-2.6] / drivers / staging / meilhaus / me1600_ao.h
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_