1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
|
#ifndef _MAX1363_H_
#define _MAX1363_H_
#define MAX1363_SETUP_BYTE(a) ((a) | 0x80)
/* There is a fair bit more defined here than currently
* used, but the intention is to support everything these
* chips do in the long run */
/* see data sheets */
/* max1363 and max1236, max1237, max1238, max1239 */
#define MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_VDD 0x00
#define MAX1363_SETUP_AIN3_IS_REF_EXT_TO_REF 0x20
#define MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_INT 0x40
#define MAX1363_SETUP_AIN3_IS_REF_REF_IS_INT 0x60
#define MAX1363_SETUP_POWER_UP_INT_REF 0x10
#define MAX1363_SETUP_POWER_DOWN_INT_REF 0x00
/* think about includeing max11600 etc - more settings */
#define MAX1363_SETUP_EXT_CLOCK 0x08
#define MAX1363_SETUP_INT_CLOCK 0x00
#define MAX1363_SETUP_UNIPOLAR 0x00
#define MAX1363_SETUP_BIPOLAR 0x04
#define MAX1363_SETUP_RESET 0x00
#define MAX1363_SETUP_NORESET 0x02
/* max1363 only - though don't care on others.
* For now monitor modes are not implemented as the relevant
* line is not connected on my test board.
* The definitions are here as I intend to add this soon.
*/
#define MAX1363_SETUP_MONITOR_SETUP 0x01
/* Specific to the max1363 */
#define MAX1363_MON_RESET_CHAN(a) (1 << ((a) + 4))
#define MAX1363_MON_INT_ENABLE 0x01
/* defined for readability reasons */
/* All chips */
#define MAX1363_CONFIG_BYTE(a) ((a))
#define MAX1363_CONFIG_SE 0x01
#define MAX1363_CONFIG_DE 0x00
#define MAX1363_CONFIG_SCAN_TO_CS 0x00
#define MAX1363_CONFIG_SCAN_SINGLE_8 0x20
#define MAX1363_CONFIG_SCAN_MONITOR_MODE 0x40
#define MAX1363_CONFIG_SCAN_SINGLE_1 0x60
/* max123{6-9} only */
#define MAX1236_SCAN_MID_TO_CHANNEL 0x40
/* max1363 only - merely part of channel selects or don't care for others*/
#define MAX1363_CONFIG_EN_MON_MODE_READ 0x18
#define MAX1363_CHANNEL_SEL(a) ((a) << 1)
/* max1363 strictly 0x06 - but doesn't matter */
#define MAX1363_CHANNEL_SEL_MASK 0x1E
#define MAX1363_SCAN_MASK 0x60
#define MAX1363_SE_DE_MASK 0x01
/**
* struct max1363_mode - scan mode information
* @conf: The corresponding value of the configuration register
* @modemask: Bit mask corresponding to channels enabled in this mode
*/
struct max1363_mode {
int8_t conf;
long modemask;
};
#define MAX1363_MODE_SINGLE(_num, _mask) { \
.conf = MAX1363_CHANNEL_SEL(_num) \
| MAX1363_CONFIG_SCAN_SINGLE_1 \
| MAX1363_CONFIG_SE, \
.modemask = _mask, \
}
#define MAX1363_MODE_SCAN_TO_CHANNEL(_num, _mask) { \
.conf = MAX1363_CHANNEL_SEL(_num) \
| MAX1363_CONFIG_SCAN_TO_CS \
| MAX1363_CONFIG_SE, \
.modemask = _mask, \
}
/* note not available for max1363 hence naming */
#define MAX1236_MODE_SCAN_MID_TO_CHANNEL(_mid, _num, _mask) { \
.conf = MAX1363_CHANNEL_SEL(_num) \
| MAX1236_SCAN_MID_TO_CHANNEL \
| MAX1363_CONFIG_SE, \
.modemask = _mask \
}
#define MAX1363_MODE_DIFF_SINGLE(_nump, _numm, _mask) { \
.conf = MAX1363_CHANNEL_SEL(_nump) \
| MAX1363_CONFIG_SCAN_SINGLE_1 \
| MAX1363_CONFIG_DE, \
.modemask = _mask \
}
/* Can't think how to automate naming so specify for now */
#define MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(_num, _numvals, _mask) { \
.conf = MAX1363_CHANNEL_SEL(_num) \
| MAX1363_CONFIG_SCAN_TO_CS \
| MAX1363_CONFIG_DE, \
.modemask = _mask \
}
/* note only available for max1363 hence naming */
#define MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(_num, _numvals, _mask) { \
.conf = MAX1363_CHANNEL_SEL(_num) \
| MAX1236_SCAN_MID_TO_CHANNEL \
| MAX1363_CONFIG_SE, \
.modemask = _mask \
}
/* This may seem an overly long winded way to do this, but at least it makes
* clear what all the various options actually do. Alternative suggestions
* that don't require user to have intimate knowledge of the chip welcomed.
*/
enum max1363_channels {
max1363_in0, max1363_in1, max1363_in2, max1363_in3,
max1363_in4, max1363_in5, max1363_in6, max1363_in7,
max1363_in8, max1363_in9, max1363_in10, max1363_in11,
max1363_in0min1, max1363_in2min3,
max1363_in4min5, max1363_in6min7,
max1363_in8min9, max1363_in10min11,
max1363_in1min0, max1363_in3min2,
max1363_in5min4, max1363_in7min6,
max1363_in9min8, max1363_in11min10,
};
/* This must be maintained along side the max1363_mode_table in max1363_core */
enum max1363_modes {
/* Single read of a single channel */
_s0, _s1, _s2, _s3, _s4, _s5, _s6, _s7, _s8, _s9, _s10, _s11,
/* Differential single read */
d0m1, d2m3, d4m5, d6m7, d8m9, d10m11,
d1m0, d3m2, d5m4, d7m6, d9m8, d11m10,
/* Scan to channel and mid to channel where overlapping */
s0to1, s0to2, s2to3, s0to3, s0to4, s0to5, s0to6,
s6to7, s0to7, s6to8, s0to8, s6to9,
s0to9, s6to10, s0to10, s6to11, s0to11,
/* Differential scan to channel and mid to channel where overlapping */
d0m1to2m3, d0m1to4m5, d0m1to6m7, d6m7to8m9,
d0m1to8m9, d6m7to10m11, d0m1to10m11, d1m0to3m2,
d1m0to5m4, d1m0to7m6, d7m6to9m8, d1m0to9m8,
d7m6to11m10, d1m0to11m10,
};
/**
* struct max1363_chip_info - chip specifc information
* @name: indentification string for chip
* @bits: accuracy of the adc in bits
* @int_vref_mv: the internal reference voltage
* @monitor_mode: whether the chip supports monitor interrupts
* @mode_list: array of available scan modes
* @num_modes: the number of scan modes available
* @default_mode: the scan mode in which the chip starts up
* @channel: channel specification
* @num_channels: number of channels
*/
struct max1363_chip_info {
u8 bits;
u16 int_vref_mv;
bool monitor_mode;
const enum max1363_modes *mode_list;
int num_modes;
enum max1363_modes default_mode;
struct iio_chan_spec *channels;
int num_channels;
};
/**
* struct max1363_state - driver instance specific data
* @client: i2c_client
* @setupbyte: cache of current device setup byte
* @configbyte: cache of current device config byte
* @chip_info: chip model specific constants, available modes etc
* @current_mode: the scan mode of this chip
* @requestedmask: a valid requested set of channels
* @poll_work: bottom half of polling interrupt handler
* @protect_ring: used to ensure only one polling bh running at a time
* @reg: supply regulator
* @monitor_on: whether monitor mode is enabled
* @monitor_speed: parameter corresponding to device monitor speed setting
* @mask_high: bitmask for enabled high thresholds
* @mask_low: bitmask for enabled low thresholds
* @thresh_high: high threshold values
* @thresh_low: low threshold values
*/
struct max1363_state {
struct i2c_client *client;
u8 setupbyte;
u8 configbyte;
const struct max1363_chip_info *chip_info;
const struct max1363_mode *current_mode;
u32 requestedmask;
struct work_struct poll_work;
atomic_t protect_ring;
struct iio_trigger *trig;
struct regulator *reg;
/* Using monitor modes and buffer at the same time is
currently not supported */
bool monitor_on;
unsigned int monitor_speed:3;
u8 mask_high;
u8 mask_low;
/* 4x unipolar first then the fours bipolar ones */
s16 thresh_high[8];
s16 thresh_low[8];
};
const struct max1363_mode
*max1363_match_mode(u32 mask, const struct max1363_chip_info *ci);
int max1363_set_scan_mode(struct max1363_state *st);
#ifdef CONFIG_MAX1363_RING_BUFFER
int max1363_single_channel_from_ring(long mask, struct max1363_state *st);
int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev);
void max1363_ring_cleanup(struct iio_dev *indio_dev);
#else /* CONFIG_MAX1363_RING_BUFFER */
int max1363_single_channel_from_ring(long mask, struct max1363_state *st)
{
return -EINVAL;
}
static inline int
max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev)
{
return 0;
}
static inline void max1363_ring_cleanup(struct iio_dev *indio_dev)
{
}
#endif /* CONFIG_MAX1363_RING_BUFFER */
#endif /* _MAX1363_H_ */
|