-
Notifications
You must be signed in to change notification settings - Fork 0
/
cf_axi_adc.h
343 lines (282 loc) · 9.94 KB
/
cf_axi_adc.h
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
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
/*
* ADI-AIM ADI ADC Interface Module
*
* Copyright 2012-2017 Analog Devices Inc.
*
* Licensed under the GPL-2.
*
* http://wiki.analog.com/resources/fpga/xilinx/fmc/ad9467
*/
#ifndef ADI_AXI_ADC_H_
#define ADI_AXI_ADC_H_
#ifdef PGMCOMOUT
#include <linux/fpga/adi-axi-common.h>
#include <linux/iio/iio.h>
#endif /* PGMCOMOUT */
/* ADC COMMON */
#define ADI_REG_CONFIG 0x000C
#define ADI_IQCORRECTION_DISABLE (1 << 0)
#define ADI_DCFILTER_DISABLE (1 << 1)
#define ADI_DATAFORMAT_DISABLE (1 << 2)
#define ADI_USERPORTS_DISABLE (1 << 3)
#define ADI_MODE_1R1T (1 << 4)
#define ADI_DELAY_CONTROL_DISABLE (1 << 5)
#define ADI_CMOS_OR_LVDS_N (1 << 7)
#define ADI_PPS_RECEIVER_ENABLE (1 << 8)
#define ADI_SCALECORRECTION_ONLY (1 << 9)
#define ADI_EXT_SYNC (1 << 12)
#define ADI_REG_RSTN 0x0040
#define ADI_RSTN (1 << 0)
#define ADI_MMCM_RSTN (1 << 1)
#define ADI_REG_CNTRL 0x0044
#define ADI_NUM_LANES(x) (((x) & 0x1F) << 8)
#define ADI_SYNC (1 << 3)
#define ADI_R1_MODE (1 << 2)
#define ADI_DDR_EDGESEL (1 << 1)
#define ADI_PIN_MODE (1 << 0)
#define ADI_REG_CNTRL_2 0x0048
#define ADI_EXT_SYNC_ARM (1 << 1)
#define ADI_EXT_SYNC_DISARM (1 << 2)
#define ADI_MANUAL_SYNC_REQUEST (1 << 8)
#define ADI_REG_CNTRL_3 0x004c
#define ADI_CRC_EN (1 << 8)
#define ADI_REG_CLK_FREQ 0x0054
#define ADI_CLK_FREQ(x) (((x) & 0xFFFFFFFF) << 0)
#define ADI_TO_CLK_FREQ(x) (((x) >> 0) & 0xFFFFFFFF)
#define ADI_REG_CLK_RATIO 0x0058
#define ADI_CLK_RATIO(x) (((x) & 0xFFFFFFFF) << 0)
#define ADI_TO_CLK_RATIO(x) (((x) >> 0) & 0xFFFFFFFF)
#define ADI_REG_STATUS 0x005C
#define ADI_MUX_PN_ERR (1 << 3)
#define ADI_MUX_PN_OOS (1 << 2)
#define ADI_MUX_OVER_RANGE (1 << 1)
#define ADI_STATUS (1 << 0)
#define ADI_REG_DELAY_CNTRL 0x0060 /* <= v8.0 */
#define ADI_DELAY_SEL (1 << 17)
#define ADI_DELAY_RWN (1 << 16)
#define ADI_DELAY_ADDRESS(x) (((x) & 0xFF) << 8)
#define ADI_TO_DELAY_ADDRESS(x) (((x) >> 8) & 0xFF)
#define ADI_DELAY_WDATA(x) (((x) & 0x1F) << 0)
#define ADI_TO_DELAY_WDATA(x) (((x) >> 0) & 0x1F)
#define ADI_REG_DELAY_STATUS 0x0064 /* <= v8.0 */
#define ADI_DELAY_LOCKED (1 << 9)
#define ADI_DELAY_STATUS (1 << 8)
#define ADI_DELAY_RDATA(x) (((x) & 0x1F) << 0)
#define ADI_TO_DELAY_RDATA(x) (((x) >> 0) & 0x1F)
#define ADI_REG_SYNC_STATUS 0x0068
#define ADI_ADC_SYNC_STATUS (1 << 0)
#define ADI_REG_DRP_CNTRL 0x0070
#define ADI_DRP_SEL (1 << 29)
#define ADI_DRP_RWN (1 << 28)
#define ADI_DRP_ADDRESS(x) (((x) & 0xFFF) << 16)
#define ADI_TO_DRP_ADDRESS(x) (((x) >> 16) & 0xFFF)
#define ADI_DRP_WDATA(x) (((x) & 0xFFFF) << 0)
#define ADI_TO_DRP_WDATA(x) (((x) >> 0) & 0xFFFF)
#define ADI_REG_DRP_STATUS 0x0074
#define ADI_DRP_STATUS (1 << 16)
#define ADI_DRP_RDATA(x) (((x) & 0xFFFF) << 0)
#define ADI_TO_DRP_RDATA(x) (((x) >> 0) & 0xFFFF)
#define ADI_REG_DMA_STATUS 0x0088
#define ADI_DMA_OVF (1 << 2)
#define ADI_DMA_UNF (1 << 1)
#define ADI_DMA_STATUS (1 << 0)
#define ADI_REG_DMA_BUSWIDTH 0x008C
#define ADI_DMA_BUSWIDTH(x) (((x) & 0xFFFFFFFF) << 0)
#define ADI_TO_DMA_BUSWIDTH(x) (((x) >> 0) & 0xFFFFFFFF)
#define ADI_REG_USR_CNTRL_1 0x00A0
#define ADI_USR_CHANMAX(x) (((x) & 0xFF) << 0)
#define ADI_TO_USR_CHANMAX(x) (((x) >> 0) & 0xFF)
#define ADI_REG_GP_CONTROL 0x00BC
#define ADI_REG_CLOCKS_PER_PPS 0x00C0
#define ADI_REG_CLOCKS_PER_PPS_STATUS 0x00C4
#define ADI_CLOCKS_PER_PPS_STAT_INVAL (1 << 0)
/* ADC CHANNEL */
#define ADI_REG_CHAN_CNTRL(c) (0x0400 + (c) * 0x40)
#define ADI_PN_SEL (1 << 10) /* !v8.0 */
#define ADI_IQCOR_ENB (1 << 9)
#define ADI_DCFILT_ENB (1 << 8)
#define ADI_FORMAT_SIGNEXT (1 << 6)
#define ADI_FORMAT_TYPE (1 << 5)
#define ADI_FORMAT_ENABLE (1 << 4)
#define ADI_PN23_TYPE (1 << 1) /* !v8.0 */
#ifndef ADI_ENABLE
#define ADI_ENABLE (1 << 0)
#endif
#define ADI_REG_CHAN_STATUS(c) (0x0404 + (c) * 0x40)
#define ADI_PN_ERR (1 << 2)
#define ADI_PN_OOS (1 << 1)
#define ADI_OVER_RANGE (1 << 0)
#define ADI_REG_CHAN_CNTRL_1(c) (0x0410 + (c) * 0x40)
#define ADI_DCFILT_OFFSET(x) (((x) & 0xFFFF) << 16)
#define ADI_TO_DCFILT_OFFSET(x) (((x) >> 16) & 0xFFFF)
#define ADI_DCFILT_COEFF(x) (((x) & 0xFFFF) << 0)
#define ADI_TO_DCFILT_COEFF(x) (((x) >> 0) & 0xFFFF)
#define ADI_REG_CHAN_CNTRL_2(c) (0x0414 + (c) * 0x40)
#define ADI_IQCOR_COEFF_1(x) (((x) & 0xFFFF) << 16)
#define ADI_TO_IQCOR_COEFF_1(x) (((x) >> 16) & 0xFFFF)
#define ADI_IQCOR_COEFF_2(x) (((x) & 0xFFFF) << 0)
#define ADI_TO_IQCOR_COEFF_2(x) (((x) >> 0) & 0xFFFF)
#define ADI_REG_CHAN_CNTRL_3(c) (0x0418 + (c) * 0x40) /* v8.0 */
#define ADI_ADC_PN_SEL(x) (((x) & 0xF) << 16)
#define ADI_TO_ADC_PN_SEL(x) (((x) >> 16) & 0xF)
#define ADI_ADC_DATA_SEL(x) (((x) & 0xF) << 0)
#define ADI_TO_ADC_DATA_SEL(x) (((x) >> 0) & 0xF)
enum adc_pn_sel {
ADC_PN9 = 0,
ADC_PN23A = 1,
ADC_PN7 = 4,
ADC_PN15 = 5,
ADC_PN23 = 6,
ADC_PN31 = 7,
ADC_PN_CUSTOM = 9,
ADC_PN_RAMP_NIBBLE = 10,
ADC_PN_RAMP_16 = 11,
ADC_PN_OFF = 12,
};
enum adc_data_sel {
ADC_DATA_SEL_NORM,
ADC_DATA_SEL_LB, /* DAC loopback */
ADC_DATA_SEL_RAMP, /* TBD */
};
#define ADI_REG_CHAN_USR_CNTRL_1(c) (0x0420 + (c) * 0x40)
#define ADI_USR_DATATYPE_BE (1 << 25)
#define ADI_USR_DATATYPE_SIGNED (1 << 24)
#define ADI_USR_DATATYPE_SHIFT(x) (((x) & 0xFF) << 16)
#define ADI_TO_USR_DATATYPE_SHIFT(x) (((x) >> 16) & 0xFF)
#define ADI_USR_DATATYPE_TOTAL_BITS(x) (((x) & 0xFF) << 8)
#define ADI_TO_USR_DATATYPE_TOTAL_BITS(x) (((x) >> 8) & 0xFF)
#define ADI_USR_DATATYPE_BITS(x) (((x) & 0xFF) << 0)
#define ADI_TO_USR_DATATYPE_BITS(x) (((x) >> 0) & 0xFF)
#define ADI_REG_CHAN_USR_CNTRL_2(c) (0x0424 + (c) * 0x40)
#define ADI_USR_DECIMATION_M(x) (((x) & 0xFFFF) << 16)
#define ADI_TO_USR_DECIMATION_M(x) (((x) >> 16) & 0xFFFF)
#define ADI_USR_DECIMATION_N(x) (((x) & 0xFFFF) << 0)
#define ADI_TO_USR_DECIMATION_N(x) (((x) >> 0) & 0xFFFF)
/* PCORE Version > 8.00 */
#define ADI_REG_DELAY(l) (0x0800 + (l) * 0x4)
/* debugfs direct register access */
#define DEBUGFS_DRA_PCORE_REG_MAGIC 0x80000000
#define AXIADC_MAX_CHANNEL 128
#include <linux/mutex.h>
#include <linux/spi/spi.h>
/**
* IIO_ENUM_AVAILABLE_SHARED() - Initialize enum available extended channel attribute
* @_name: Attribute name ("_available" will be appended to the name)
* @_shared: Whether the attribute is shared between all channels
* @_e: Pointer to an iio_enum struct
*
* Creates a read only attribute which lists all the available enum items in a
* space separated list. This should usually be used together with IIO_ENUM()
*/
#define IIO_ENUM_AVAILABLE_SHARED(_name, _shared, _e) \
{ \
.name = (_name "_available"), \
.shared = _shared, \
.read = iio_enum_available_read, \
.private = (uintptr_t)(_e), \
}
#ifdef PGMCOMOUT
#include <linux/clk/clkscale.h>
#endif
struct axiadc_state;
struct clock_scale {};
struct axiadc_chip_info {
unsigned int id;
char *name;
unsigned num_channels;
unsigned num_shadow_slave_channels;
const unsigned long *scan_masks;
const int (*scale_table)[2];
int num_scales;
int max_testmode;
unsigned long max_rate;
struct iio_chan_spec channel[AXIADC_MAX_CHANNEL];
};
struct axiadc_converter {
struct spi_device *spi;
struct clk *clk;
struct clock_scale adc_clkscale;
struct clk *lane_clk;
struct clk *sysref_clk;
struct clk *out_clk;
void *phy;
struct gpio_desc *pwrdown_gpio;
struct gpio_desc *reset_gpio;
unsigned id;
unsigned adc_output_mode;
unsigned testmode[AXIADC_MAX_CHANNEL];
unsigned scratch_reg[AXIADC_MAX_CHANNEL];
unsigned long adc_clk;
const struct axiadc_chip_info *chip_info;
struct delayed_work watchdog_work;
bool sample_rate_read_only;
bool running;
int (*reg_access)(struct iio_dev *indio_dev, unsigned int reg,
unsigned int writeval, unsigned int *readval);
struct iio_chan_spec const *channels;
int num_channels;
const struct attribute_group *attrs;
struct iio_dev *indio_dev;
/*
* shared lock between the converter and axi_adc to sync
* accesses/configurations to/with the IP core. The axi_adc driver is
* responsible to initialize this lock.
*/
struct mutex lock;
int (*read_raw)(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val,
int *val2,
long mask);
int (*write_raw)(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int val,
int val2,
long mask);
int (*read_event_value)(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
enum iio_event_type type,
enum iio_event_direction dir,
enum iio_event_info info,
int *val,
int *val2);
int (*write_event_value)(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
enum iio_event_type type,
enum iio_event_direction dir,
enum iio_event_info info,
int val,
int val2);
int (*read_event_config)(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan,
enum iio_event_type type,
enum iio_event_direction dir);
int (*write_event_config)(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan,
enum iio_event_type type,
enum iio_event_direction dir,
int state);
int (*read_label)(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan, char *label);
int (*post_setup)(struct iio_dev *indio_dev);
int (*post_iio_register)(struct iio_dev *indio_dev);
int (*set_pnsel)(struct iio_dev *indio_dev, unsigned chan,
enum adc_pn_sel sel);
};
struct axiadc_converter *to_converter(struct device *dev);
/*
* IO accessors
*/
void axiadc_write(struct axiadc_state *st, unsigned int reg, unsigned int val);
unsigned int axiadc_read(struct axiadc_state *st, unsigned int reg);
void axiadc_slave_write(struct axiadc_state *st, unsigned int reg,
unsigned int val);
unsigned int axiadc_slave_read(struct axiadc_state *st, unsigned int reg);
void axiadc_idelay_set(struct axiadc_state *st, unsigned int lane,
unsigned int val);
int axiadc_set_pnsel(struct axiadc_state *st, int channel, enum adc_pn_sel sel);
enum adc_pn_sel axiadc_get_pnsel(struct axiadc_state *st,
int channel, const char **name);
#ifdef PGMCOMOUT
#endif /* PGMCOMOUT */
#endif /* ADI_AXI_ADC_H_ */