1 /*
2 * Copyright (C) 2016 Analog Devices, Inc.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 */
14
15 #include "ad9361.h"
16
17 #include <errno.h>
18 #include <iio.h>
19 #include <stdio.h>
20 #ifdef _WIN32
21 #include <windows.h>
22 #else
23 #include <unistd.h>
24 #endif
25
26 #ifdef _MSC_BUILD
27 #define snprintf sprintf_s
28 #endif
29
30 static int16_t fir_128_4[] = {
31 -15,-27,-23,-6,17,33,31,9,-23,-47,-45,-13,34,69,67,21,-49,-102,-99,-32,69,146,143,48,-96,-204,-200,-69,129,278,275,97,-170,
32 -372,-371,-135,222,494,497,187,-288,-654,-665,-258,376,875,902,363,-500,-1201,-1265,-530,699,1748,1906,845,-1089,-2922,-3424,
33 -1697,2326,7714,12821,15921,15921,12821,7714,2326,-1697,-3424,-2922,-1089,845,1906,1748,699,-530,-1265,-1201,-500,363,902,875,
34 376,-258,-665,-654,-288,187,497,494,222,-135,-371,-372,-170,97,275,278,129,-69,-200,-204,-96,48,143,146,69,-32,-99,-102,-49,21,
35 67,69,34,-13,-45,-47,-23,9,31,33,17,-6,-23,-27,-15};
36
37 static int16_t fir_128_2[] = {
38 -0,0,1,-0,-2,0,3,-0,-5,0,8,-0,-11,0,17,-0,-24,0,33,-0,-45,0,61,-0,-80,0,104,-0,-134,0,169,-0,
39 -213,0,264,-0,-327,0,401,-0,-489,0,595,-0,-724,0,880,-0,-1075,0,1323,-0,-1652,0,2114,-0,-2819,0,4056,-0,-6883,0,20837,32767,
40 20837,0,-6883,-0,4056,0,-2819,-0,2114,0,-1652,-0,1323,0,-1075,-0,880,0,-724,-0,595,0,-489,-0,401,0,-327,-0,264,0,-213,-0,
41 169,0,-134,-0,104,0,-80,-0,61,0,-45,-0,33,0,-24,-0,17,0,-11,-0,8,0,-5,-0,3,0,-2,-0,1,0,-0, 0 };
42
43 static int16_t fir_96_2[] = {
44 -4,0,8,-0,-14,0,23,-0,-36,0,52,-0,-75,0,104,-0,-140,0,186,-0,-243,0,314,-0,-400,0,505,-0,-634,0,793,-0,
45 -993,0,1247,-0,-1585,0,2056,-0,-2773,0,4022,-0,-6862,0,20830,32767,20830,0,-6862,-0,4022,0,-2773,-0,2056,0,-1585,-0,1247,0,-993,-0,
46 793,0,-634,-0,505,0,-400,-0,314,0,-243,-0,186,0,-140,-0,104,0,-75,-0,52,0,-36,-0,23,0,-14,-0,8,0,-4,0};
47
48 static int16_t fir_64_2[] = {
49 -58,0,83,-0,-127,0,185,-0,-262,0,361,-0,-488,0,648,-0,-853,0,1117,-0,-1466,0,1954,-0,-2689,0,3960,-0,-6825,0,20818,32767,
50 20818,0,-6825,-0,3960,0,-2689,-0,1954,0,-1466,-0,1117,0,-853,-0,648,0,-488,-0,361,0,-262,-0,185,0,-127,-0,83,0,-58,0};
51
52 #define FIR_BUF_SIZE 8192
53
ad9361_set_trx_fir_enable(struct iio_device * dev,int enable)54 int ad9361_set_trx_fir_enable(struct iio_device *dev, int enable)
55 {
56 int ret = iio_device_attr_write_bool(dev,
57 "in_out_voltage_filter_fir_en", !!enable);
58 if (ret < 0)
59 ret = iio_channel_attr_write_bool(iio_device_find_channel(dev, "out", false),
60 "voltage_filter_fir_en", !!enable);
61 return ret;
62 }
63
ad9361_get_trx_fir_enable(struct iio_device * dev,int * enable)64 int ad9361_get_trx_fir_enable(struct iio_device *dev, int *enable)
65 {
66 bool value;
67
68 int ret = iio_device_attr_read_bool(dev, "in_out_voltage_filter_fir_en", &value);
69
70 if (ret < 0)
71 ret = iio_channel_attr_read_bool(iio_device_find_channel(dev, "out", false),
72 "voltage_filter_fir_en", &value);
73
74 if (!ret)
75 *enable = value;
76
77 return ret;
78 }
79
ad9361_set_bb_rate(struct iio_device * dev,unsigned long rate)80 int ad9361_set_bb_rate(struct iio_device *dev, unsigned long rate)
81 {
82 struct iio_channel *chan;
83 long long current_rate;
84 int dec, taps, ret, i, enable, len = 0;
85 int16_t *fir;
86 char *buf;
87
88 if (rate <= 20000000UL) {
89 dec = 4;
90 taps = 128;
91 fir = fir_128_4;
92 } else if (rate <= 40000000UL) {
93 dec = 2;
94 fir = fir_128_2;
95 taps = 128;
96 } else if (rate <= 53333333UL) {
97 dec = 2;
98 fir = fir_96_2;
99 taps = 96;
100 } else {
101 dec = 2;
102 fir = fir_64_2;
103 taps = 64;
104 }
105
106 chan = iio_device_find_channel(dev, "voltage0", true);
107 if (chan == NULL)
108 return -ENODEV;
109
110 ret = iio_channel_attr_read_longlong(chan, "sampling_frequency", ¤t_rate);
111 if (ret < 0)
112 return ret;
113
114 ret = ad9361_get_trx_fir_enable(dev, &enable);
115 if (ret < 0)
116 return ret;
117
118 if (enable) {
119 if (current_rate <= (25000000 / 12))
120 iio_channel_attr_write_longlong(chan, "sampling_frequency", 3000000);
121
122 ret = ad9361_set_trx_fir_enable(dev, false);
123 if (ret < 0)
124 return ret;
125 }
126
127 buf = malloc(FIR_BUF_SIZE);
128 if (!buf)
129 return -ENOMEM;
130
131 len += snprintf(buf + len, FIR_BUF_SIZE - len, "RX 3 GAIN -6 DEC %d\n", dec);
132 len += snprintf(buf + len, FIR_BUF_SIZE - len, "TX 3 GAIN 0 INT %d\n", dec);
133
134 for (i = 0; i < taps; i++)
135 len += snprintf(buf + len, FIR_BUF_SIZE - len, "%d,%d\n", fir[i], fir[i]);
136
137 len += snprintf(buf + len, FIR_BUF_SIZE - len, "\n");
138
139 ret = iio_device_attr_write_raw(dev, "filter_fir_config", buf, len);
140 free (buf);
141
142 if (ret < 0)
143 return ret;
144
145 if (rate <= (25000000 / 12)) {
146 int dacrate, txrate, max;
147 char readbuf[100];
148
149 ret = iio_device_attr_read(dev, "tx_path_rates", readbuf, sizeof(readbuf));
150 if (ret < 0)
151 return ret;
152 ret = sscanf(readbuf, "BBPLL:%*d DAC:%d T2:%*d T1:%*d TF:%*d TXSAMP:%d", &dacrate, &txrate);
153 if (ret != 2)
154 return -EFAULT;
155
156 if (txrate == 0)
157 return -EINVAL;
158
159 max = (dacrate / txrate) * 16;
160 if (max < taps)
161 iio_channel_attr_write_longlong(chan, "sampling_frequency", 3000000);
162
163 ret = ad9361_set_trx_fir_enable(dev, true);
164 if (ret < 0)
165 return ret;
166 ret = iio_channel_attr_write_longlong(chan, "sampling_frequency", rate);
167 if (ret < 0)
168 return ret;
169 } else {
170 ret = iio_channel_attr_write_longlong(chan, "sampling_frequency", rate);
171 if (ret < 0)
172 return ret;
173 ret = ad9361_set_trx_fir_enable(dev, true);
174 if (ret < 0)
175 return ret;
176 }
177
178 return 0;
179 }
180