Statistics
| Branch: | Tag: | Revision:

root / host / lib / usrp / dboard / db_tvrx2.cpp @ a5aece05

History | View | Annotate | Download (81.5 KB)

1
//
2
// Copyright 2010 Ettus Research LLC
3
//
4
// This program is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// This program 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
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
//
17

    
18
// Common IO Pins
19
#define REFCLOCK_DIV_MASK    ((1 << 8)|(1 << 9)|(1 << 10))    // Three GPIO lines to CPLD for Clock Divisor Selection
20
#define REFCLOCK_DIV8        ((1 << 8)|(1 << 9)|(1 << 10))    // GPIO to set clock div8 mode
21
#define REFCLOCK_DIV7        ((0 << 8)|(1 << 9)|(1 << 10))    // GPIO to set clock div7 mode
22
#define REFCLOCK_DIV6        ((1 << 8)|(0 << 9)|(1 << 10))    // GPIO to set clock div6 mode
23
#define REFCLOCK_DIV5        ((0 << 8)|(0 << 9)|(1 << 10))    // GPIO to set clock div5 mode
24
#define REFCLOCK_DIV4        ((1 << 8)|(1 <<9))               // GPIO to set clock div4 mode
25
#define REFCLOCK_DIV3        (1 <<9)                          // GPIO to set clock div3 mode
26
#define REFCLOCK_DIV2        (1 <<8)                          // GPIO to set clock div2 mode
27
#define REFCLOCK_DIV1        ((0 << 8)|(0 << 9)|(0 << 10))    // GPIO to set clock div1 mode
28

    
29
// RX1 IO Pins
30
#define RX1_MASTERSYNC  (1 << 3)                // MASTERSYNC Signal for Slave Tuner Coordination
31
#define RX1_FREEZE      (1 << 2)                // FREEZE Signal for Slave Tuner Coordination
32
#define RX1_IRQ         (1 << 1)                // IRQ Signals TDA18272HNM State Machine Completion
33
#define RX1_VSYNC       (1 << 0)                // VSYNC Pulse for AGC Holdoff
34

    
35
// RX2 IO Pins
36
#define RX2_MASTERSYNC  (1 << 7)                // MASTERSYNC Signal for Slave Tuner Coordination
37
#define RX2_FREEZE      (1 << 6)                // FREEZE Signal for Slave Tuner Coordination
38
#define RX2_IRQ         (1 << 5)                // IRQ Signals TDA18272HNM State Machine Completion
39
#define RX2_VSYNC       (1 << 4)                // VSYNC Pulse for AGC Holdoff
40

    
41
// Pin functions
42
#define RX1_OUTPUT_MASK (0)
43
#define RX1_INPUT_MASK  (RX1_VSYNC|RX1_MASTERSYNC|RX1_FREEZE|RX1_IRQ)
44

    
45
#define RX2_OUTPUT_MASK (0)
46
#define RX2_INPUT_MASK  (RX2_VSYNC|RX2_MASTERSYNC|RX2_FREEZE|RX2_IRQ)
47

    
48
#define OUTPUT_MASK     (RX1_OUTPUT_MASK|RX2_OUTPUT_MASK|REFCLOCK_DIV_MASK)
49
#define INPUT_MASK      (RX1_INPUT_MASK|RX2_INPUT_MASK)
50

    
51

    
52
#include "tda18272hnm_regs.hpp"
53
#include <uhd/utils/static.hpp>
54
#include <uhd/utils/log.hpp>
55
#include <uhd/utils/msg.hpp>
56
#include <uhd/utils/assert_has.hpp>
57
#include <uhd/utils/algorithm.hpp>
58
#include <uhd/types/ranges.hpp>
59
#include <uhd/types/sensors.hpp>
60
#include <uhd/types/dict.hpp>
61
#include <uhd/usrp/subdev_props.hpp>
62
#include <uhd/usrp/dboard_base.hpp>
63
#include <uhd/usrp/dboard_manager.hpp>
64
#include <boost/assign/list_of.hpp>
65
#include <boost/format.hpp>
66
#include <boost/thread.hpp>
67
#include <boost/array.hpp>
68
#include <boost/math/special_functions/round.hpp>
69
#include <utility>
70
#include <cmath>
71

    
72
using namespace uhd;
73
using namespace uhd::usrp;
74
using namespace boost::assign;
75

    
76
/***********************************************************************
77
 * The TVRX2 types
78
 **********************************************************************/
79
struct tvrx2_tda18272_rfcal_result_t {
80
    boost::int8_t    delta_c;
81
    boost::int8_t    c_offset;
82
    tvrx2_tda18272_rfcal_result_t(void): delta_c(0), c_offset(0){}
83
};
84

    
85
struct tvrx2_tda18272_rfcal_coeffs_t  {
86
    boost::uint8_t   cal_number;
87
    boost::int32_t   RF_A1;
88
    boost::int32_t   RF_B1;
89
    tvrx2_tda18272_rfcal_coeffs_t(void): cal_number(0), RF_A1(0), RF_B1(0) {}
90
    tvrx2_tda18272_rfcal_coeffs_t(boost::uint32_t num): RF_A1(0), RF_B1(0) { cal_number = num; }
91
};
92

    
93
struct tvrx2_tda18272_cal_map_t {
94
    boost::array<boost::uint32_t, 4>  cal_freq;
95
    boost::array<boost::uint8_t, 4>   c_offset;
96
    tvrx2_tda18272_cal_map_t(boost::array<boost::uint32_t, 4> freqs, boost::array<boost::uint8_t, 4> offsets)
97
        { cal_freq = freqs; c_offset = offsets; }
98
};
99

    
100
struct tvrx2_tda18272_freq_map_t {
101
    boost::uint32_t  rf_max;
102
    boost::uint8_t   c_prog;
103
    boost::uint8_t   gain_taper;
104
    boost::uint8_t   rf_band;
105
    tvrx2_tda18272_freq_map_t( boost::uint32_t max, boost::uint8_t c, boost::uint8_t taper, boost::uint8_t band)
106
        { rf_max = max; c_prog = c; gain_taper = taper; rf_band = band; }
107
};
108

    
109
/***********************************************************************
110
 * The TVRX2 constants
111
 **********************************************************************/
112

    
113
static const boost::array<freq_range_t, 4> tvrx2_tda18272_rf_bands = list_of
114
    ( freq_range_t(  44.056e6, 144.408e6) )
115
    ( freq_range_t( 145.432e6, 361.496e6) )
116
    ( freq_range_t( 365.592e6, 618.520e6) )
117
    ( freq_range_t( 619.544e6, 865.304e6) )
118
;
119

    
120
#define TVRX2_TDA18272_FREQ_MAP_ENTRIES (565)
121

    
122
static const uhd::dict<boost::uint32_t, tvrx2_tda18272_cal_map_t> tvrx2_tda18272_cal_map = map_list_of
123
    (  0, tvrx2_tda18272_cal_map_t( list_of( 44032000)( 48128000)( 52224000)( 56320000), list_of(15)( 0)(10)(17) ) )
124
    (  1, tvrx2_tda18272_cal_map_t( list_of( 84992000)( 89088000)( 93184000)( 97280000), list_of( 1)( 0)(-2)( 3) ) )
125
    (  2, tvrx2_tda18272_cal_map_t( list_of(106496000)(111616000)(115712000)(123904000), list_of( 0)(-1)( 1)( 2) ) )
126
    (  3, tvrx2_tda18272_cal_map_t( list_of(161792000)(165888000)(169984000)(174080000), list_of( 3)( 0)( 1)( 2) ) )
127
    (  4, tvrx2_tda18272_cal_map_t( list_of(224256000)(228352000)(232448000)(235520000), list_of( 3)( 0)( 1)( 2) ) )
128
    (  5, tvrx2_tda18272_cal_map_t( list_of(301056000)(312320000)(322560000)(335872000), list_of( 0)(-1)( 1)( 2) ) )
129
    (  6, tvrx2_tda18272_cal_map_t( list_of(389120000)(393216000)(397312000)(401408000), list_of(-2)( 0)(-1)( 1) ) )
130
    (  7, tvrx2_tda18272_cal_map_t( list_of(455680000)(460800000)(465920000)(471040000), list_of( 0)(-2)(-3)( 1) ) )
131
    (  8, tvrx2_tda18272_cal_map_t( list_of(555008000)(563200000)(570368000)(577536000), list_of(-1)( 0)(-3)(-2) ) )
132
    (  9, tvrx2_tda18272_cal_map_t( list_of(647168000)(652288000)(658432000)(662528000), list_of(-6)(-3)( 0)(-5) ) )
133
    ( 10, tvrx2_tda18272_cal_map_t( list_of(748544000)(755712000)(762880000)(770048000), list_of(-6)(-3)( 0)(-5) ) )
134
    ( 11, tvrx2_tda18272_cal_map_t( list_of(792576000)(801792000)(809984000)(818176000), list_of(-5)(-2)( 0)(-4) ) )
135
;
136

    
137
static const std::vector<tvrx2_tda18272_freq_map_t> tvrx2_tda18272_freq_map = list_of
138
    ( tvrx2_tda18272_freq_map_t( 39936000, 0xFF, 0x17, 0) )
139
    ( tvrx2_tda18272_freq_map_t( 40960000, 0xFD, 0x17, 0) )
140
    ( tvrx2_tda18272_freq_map_t( 41984000, 0xF1, 0x15, 0) )
141
    ( tvrx2_tda18272_freq_map_t( 43008000, 0xE5, 0x13, 0) )
142
    ( tvrx2_tda18272_freq_map_t( 44032000, 0xDB, 0x13, 0) )
143
    ( tvrx2_tda18272_freq_map_t( 45056000, 0xD1, 0x12, 0) )
144
    ( tvrx2_tda18272_freq_map_t( 46080000, 0xC7, 0x10, 0) )
145
    ( tvrx2_tda18272_freq_map_t( 47104000, 0xBE, 0x0F, 0) )
146
    ( tvrx2_tda18272_freq_map_t( 48128000, 0xB5, 0x0F, 0) )
147
    ( tvrx2_tda18272_freq_map_t( 49152000, 0xAD, 0x0F, 0) )
148
    ( tvrx2_tda18272_freq_map_t( 50176000, 0xA6, 0x0F, 0) )
149
    ( tvrx2_tda18272_freq_map_t( 51200000, 0x9F, 0x0F, 0) )
150
    ( tvrx2_tda18272_freq_map_t( 52224000, 0x98, 0x0F, 0) )
151
    ( tvrx2_tda18272_freq_map_t( 53248000, 0x91, 0x0F, 0) )
152
    ( tvrx2_tda18272_freq_map_t( 54272000, 0x8B, 0x0F, 0) )
153
    ( tvrx2_tda18272_freq_map_t( 55296000, 0x86, 0x0F, 0) )
154
    ( tvrx2_tda18272_freq_map_t( 56320000, 0x80, 0x0F, 0) )
155
    ( tvrx2_tda18272_freq_map_t( 57344000, 0x7B, 0x0E, 0) )
156
    ( tvrx2_tda18272_freq_map_t( 58368000, 0x76, 0x0E, 0) )
157
    ( tvrx2_tda18272_freq_map_t( 59392000, 0x72, 0x0D, 0) )
158
    ( tvrx2_tda18272_freq_map_t( 60416000, 0x6D, 0x0D, 0) )
159
    ( tvrx2_tda18272_freq_map_t( 61440000, 0x69, 0x0C, 0) )
160
    ( tvrx2_tda18272_freq_map_t( 62464000, 0x65, 0x0C, 0) )
161
    ( tvrx2_tda18272_freq_map_t( 63488000, 0x61, 0x0B, 0) )
162
    ( tvrx2_tda18272_freq_map_t( 64512000, 0x5E, 0x0B, 0) )
163
    ( tvrx2_tda18272_freq_map_t( 64512000, 0x5A, 0x0B, 0) )
164
    ( tvrx2_tda18272_freq_map_t( 65536000, 0x57, 0x0A, 0) )
165
    ( tvrx2_tda18272_freq_map_t( 66560000, 0x54, 0x0A, 0) )
166
    ( tvrx2_tda18272_freq_map_t( 67584000, 0x51, 0x09, 0) )
167
    ( tvrx2_tda18272_freq_map_t( 68608000, 0x4E, 0x09, 0) )
168
    ( tvrx2_tda18272_freq_map_t( 69632000, 0x4B, 0x09, 0) )
169
    ( tvrx2_tda18272_freq_map_t( 70656000, 0x49, 0x08, 0) )
170
    ( tvrx2_tda18272_freq_map_t( 71680000, 0x46, 0x08, 0) )
171
    ( tvrx2_tda18272_freq_map_t( 72704000, 0x44, 0x08, 0) )
172
    ( tvrx2_tda18272_freq_map_t( 73728000, 0x41, 0x07, 0) )
173
    ( tvrx2_tda18272_freq_map_t( 74752000, 0x3F, 0x07, 0) )
174
    ( tvrx2_tda18272_freq_map_t( 75776000, 0x3D, 0x07, 0) )
175
    ( tvrx2_tda18272_freq_map_t( 76800000, 0x3B, 0x07, 0) )
176
    ( tvrx2_tda18272_freq_map_t( 77824000, 0x39, 0x07, 0) )
177
    ( tvrx2_tda18272_freq_map_t( 78848000, 0x37, 0x07, 0) )
178
    ( tvrx2_tda18272_freq_map_t( 79872000, 0x35, 0x07, 0) )
179
    ( tvrx2_tda18272_freq_map_t( 80896000, 0x33, 0x07, 0) )
180
    ( tvrx2_tda18272_freq_map_t( 81920000, 0x32, 0x07, 0) )
181
    ( tvrx2_tda18272_freq_map_t( 82944000, 0x30, 0x07, 0) )
182
    ( tvrx2_tda18272_freq_map_t( 83968000, 0x2F, 0x07, 0) )
183
    ( tvrx2_tda18272_freq_map_t( 84992000, 0x2D, 0x07, 0) )
184
    ( tvrx2_tda18272_freq_map_t( 86016000, 0x2C, 0x07, 0) )
185
    ( tvrx2_tda18272_freq_map_t( 87040000, 0x2A, 0x07, 0) )
186
    ( tvrx2_tda18272_freq_map_t( 88064000, 0x29, 0x06, 0) )
187
    ( tvrx2_tda18272_freq_map_t( 89088000, 0x27, 0x06, 0) )
188
    ( tvrx2_tda18272_freq_map_t( 90112000, 0x26, 0x06, 0) )
189
    ( tvrx2_tda18272_freq_map_t( 91136000, 0x25, 0x06, 0) )
190
    ( tvrx2_tda18272_freq_map_t( 92160000, 0x24, 0x06, 0) )
191
    ( tvrx2_tda18272_freq_map_t( 93184000, 0x22, 0x05, 0) )
192
    ( tvrx2_tda18272_freq_map_t( 94208000, 0x21, 0x05, 0) )
193
    ( tvrx2_tda18272_freq_map_t( 95232000, 0x20, 0x05, 0) )
194
    ( tvrx2_tda18272_freq_map_t( 96256000, 0x1F, 0x05, 0) )
195
    ( tvrx2_tda18272_freq_map_t( 97280000, 0x1E, 0x05, 0) )
196
    ( tvrx2_tda18272_freq_map_t( 98304000, 0x1D, 0x05, 0) )
197
    ( tvrx2_tda18272_freq_map_t( 99328000, 0x1C, 0x04, 0) )
198
    ( tvrx2_tda18272_freq_map_t(100352000, 0x1B, 0x04, 0) )
199
    ( tvrx2_tda18272_freq_map_t(101376000, 0x1A, 0x04, 0) )
200
    ( tvrx2_tda18272_freq_map_t(103424000, 0x19, 0x04, 0) )
201
    ( tvrx2_tda18272_freq_map_t(104448000, 0x18, 0x04, 0) )
202
    ( tvrx2_tda18272_freq_map_t(105472000, 0x17, 0x04, 0) )
203
    ( tvrx2_tda18272_freq_map_t(106496000, 0x16, 0x03, 0) )
204
    ( tvrx2_tda18272_freq_map_t(106496000, 0x15, 0x03, 0) )
205
    ( tvrx2_tda18272_freq_map_t(108544000, 0x14, 0x03, 0) )
206
    ( tvrx2_tda18272_freq_map_t(109568000, 0x13, 0x03, 0) )
207
    ( tvrx2_tda18272_freq_map_t(111616000, 0x12, 0x03, 0) )
208
    ( tvrx2_tda18272_freq_map_t(112640000, 0x11, 0x03, 0) )
209
    ( tvrx2_tda18272_freq_map_t(113664000, 0x11, 0x07, 0) )
210
    ( tvrx2_tda18272_freq_map_t(114688000, 0x10, 0x07, 0) )
211
    ( tvrx2_tda18272_freq_map_t(115712000, 0x0F, 0x07, 0) )
212
    ( tvrx2_tda18272_freq_map_t(117760000, 0x0E, 0x07, 0) )
213
    ( tvrx2_tda18272_freq_map_t(119808000, 0x0D, 0x06, 0) )
214
    ( tvrx2_tda18272_freq_map_t(121856000, 0x0C, 0x06, 0) )
215
    ( tvrx2_tda18272_freq_map_t(123904000, 0x0B, 0x06, 0) )
216
    ( tvrx2_tda18272_freq_map_t(125952000, 0x0A, 0x05, 0) )
217
    ( tvrx2_tda18272_freq_map_t(128000000, 0x09, 0x05, 0) )
218
    ( tvrx2_tda18272_freq_map_t(130048000, 0x08, 0x05, 0) )
219
    ( tvrx2_tda18272_freq_map_t(133120000, 0x07, 0x04, 0) )
220
    ( tvrx2_tda18272_freq_map_t(135168000, 0x06, 0x04, 0) )
221
    ( tvrx2_tda18272_freq_map_t(138240000, 0x05, 0x04, 0) )
222
    ( tvrx2_tda18272_freq_map_t(141312000, 0x04, 0x04, 0) )
223
    ( tvrx2_tda18272_freq_map_t(144384000, 0x03, 0x03, 0) )
224
    ( tvrx2_tda18272_freq_map_t(145408000, 0xE0, 0x3F, 1) )
225
    ( tvrx2_tda18272_freq_map_t(147456000, 0xDC, 0x37, 1) )
226
    ( tvrx2_tda18272_freq_map_t(148480000, 0xD9, 0x32, 1) )
227
    ( tvrx2_tda18272_freq_map_t(149504000, 0xD6, 0x2F, 1) )
228
    ( tvrx2_tda18272_freq_map_t(149504000, 0xD2, 0x2F, 1) )
229
    ( tvrx2_tda18272_freq_map_t(150528000, 0xCF, 0x2F, 1) )
230
    ( tvrx2_tda18272_freq_map_t(151552000, 0xCC, 0x2B, 1) )
231
    ( tvrx2_tda18272_freq_map_t(152576000, 0xC9, 0x27, 1) )
232
    ( tvrx2_tda18272_freq_map_t(153600000, 0xC5, 0x27, 1) )
233
    ( tvrx2_tda18272_freq_map_t(154624000, 0xC2, 0x25, 1) )
234
    ( tvrx2_tda18272_freq_map_t(155648000, 0xBF, 0x23, 1) )
235
    ( tvrx2_tda18272_freq_map_t(156672000, 0xBD, 0x20, 1) )
236
    ( tvrx2_tda18272_freq_map_t(157696000, 0xBA, 0x1F, 1) )
237
    ( tvrx2_tda18272_freq_map_t(158720000, 0xB7, 0x1F, 1) )
238
    ( tvrx2_tda18272_freq_map_t(159744000, 0xB4, 0x1F, 1) )
239
    ( tvrx2_tda18272_freq_map_t(160768000, 0xB1, 0x1F, 1) )
240
    ( tvrx2_tda18272_freq_map_t(161792000, 0xAF, 0x1F, 1) )
241
    ( tvrx2_tda18272_freq_map_t(162816000, 0xAC, 0x1F, 1) )
242
    ( tvrx2_tda18272_freq_map_t(163840000, 0xAA, 0x1F, 1) )
243
    ( tvrx2_tda18272_freq_map_t(164864000, 0xA7, 0x1F, 1) )
244
    ( tvrx2_tda18272_freq_map_t(165888000, 0xA5, 0x1F, 1) )
245
    ( tvrx2_tda18272_freq_map_t(166912000, 0xA2, 0x1F, 1) )
246
    ( tvrx2_tda18272_freq_map_t(167936000, 0xA0, 0x1F, 1) )
247
    ( tvrx2_tda18272_freq_map_t(168960000, 0x9D, 0x1F, 1) )
248
    ( tvrx2_tda18272_freq_map_t(169984000, 0x9B, 0x1F, 1) )
249
    ( tvrx2_tda18272_freq_map_t(171008000, 0x99, 0x1F, 1) )
250
    ( tvrx2_tda18272_freq_map_t(172032000, 0x97, 0x1E, 1) )
251
    ( tvrx2_tda18272_freq_map_t(173056000, 0x95, 0x1D, 1) )
252
    ( tvrx2_tda18272_freq_map_t(174080000, 0x92, 0x1C, 1) )
253
    ( tvrx2_tda18272_freq_map_t(175104000, 0x90, 0x1B, 1) )
254
    ( tvrx2_tda18272_freq_map_t(176128000, 0x8E, 0x1A, 1) )
255
    ( tvrx2_tda18272_freq_map_t(177152000, 0x8C, 0x19, 1) )
256
    ( tvrx2_tda18272_freq_map_t(178176000, 0x8A, 0x18, 1) )
257
    ( tvrx2_tda18272_freq_map_t(179200000, 0x88, 0x17, 1) )
258
    ( tvrx2_tda18272_freq_map_t(180224000, 0x86, 0x17, 1) )
259
    ( tvrx2_tda18272_freq_map_t(181248000, 0x84, 0x17, 1) )
260
    ( tvrx2_tda18272_freq_map_t(182272000, 0x82, 0x17, 1) )
261
    ( tvrx2_tda18272_freq_map_t(183296000, 0x81, 0x17, 1) )
262
    ( tvrx2_tda18272_freq_map_t(184320000, 0x7F, 0x17, 1) )
263
    ( tvrx2_tda18272_freq_map_t(185344000, 0x7D, 0x16, 1) )
264
    ( tvrx2_tda18272_freq_map_t(186368000, 0x7B, 0x15, 1) )
265
    ( tvrx2_tda18272_freq_map_t(187392000, 0x7A, 0x14, 1) )
266
    ( tvrx2_tda18272_freq_map_t(188416000, 0x78, 0x14, 1) )
267
    ( tvrx2_tda18272_freq_map_t(189440000, 0x76, 0x13, 1) )
268
    ( tvrx2_tda18272_freq_map_t(190464000, 0x75, 0x13, 1) )
269
    ( tvrx2_tda18272_freq_map_t(191488000, 0x73, 0x13, 1) )
270
    ( tvrx2_tda18272_freq_map_t(192512000, 0x71, 0x12, 1) )
271
    ( tvrx2_tda18272_freq_map_t(192512000, 0x70, 0x11, 1) )
272
    ( tvrx2_tda18272_freq_map_t(193536000, 0x6E, 0x11, 1) )
273
    ( tvrx2_tda18272_freq_map_t(194560000, 0x6D, 0x10, 1) )
274
    ( tvrx2_tda18272_freq_map_t(195584000, 0x6B, 0x10, 1) )
275
    ( tvrx2_tda18272_freq_map_t(196608000, 0x6A, 0x0F, 1) )
276
    ( tvrx2_tda18272_freq_map_t(197632000, 0x68, 0x0F, 1) )
277
    ( tvrx2_tda18272_freq_map_t(198656000, 0x67, 0x0F, 1) )
278
    ( tvrx2_tda18272_freq_map_t(199680000, 0x65, 0x0F, 1) )
279
    ( tvrx2_tda18272_freq_map_t(200704000, 0x64, 0x0F, 1) )
280
    ( tvrx2_tda18272_freq_map_t(201728000, 0x63, 0x0F, 1) )
281
    ( tvrx2_tda18272_freq_map_t(202752000, 0x61, 0x0F, 1) )
282
    ( tvrx2_tda18272_freq_map_t(203776000, 0x60, 0x0F, 1) )
283
    ( tvrx2_tda18272_freq_map_t(204800000, 0x5F, 0x0F, 1) )
284
    ( tvrx2_tda18272_freq_map_t(205824000, 0x5D, 0x0F, 1) )
285
    ( tvrx2_tda18272_freq_map_t(206848000, 0x5C, 0x0F, 1) )
286
    ( tvrx2_tda18272_freq_map_t(207872000, 0x5B, 0x0F, 1) )
287
    ( tvrx2_tda18272_freq_map_t(208896000, 0x5A, 0x0F, 1) )
288
    ( tvrx2_tda18272_freq_map_t(209920000, 0x58, 0x0F, 1) )
289
    ( tvrx2_tda18272_freq_map_t(210944000, 0x57, 0x0F, 1) )
290
    ( tvrx2_tda18272_freq_map_t(211968000, 0x56, 0x0F, 1) )
291
    ( tvrx2_tda18272_freq_map_t(212992000, 0x55, 0x0F, 1) )
292
    ( tvrx2_tda18272_freq_map_t(214016000, 0x54, 0x0F, 1) )
293
    ( tvrx2_tda18272_freq_map_t(215040000, 0x53, 0x0F, 1) )
294
    ( tvrx2_tda18272_freq_map_t(216064000, 0x52, 0x0F, 1) )
295
    ( tvrx2_tda18272_freq_map_t(217088000, 0x50, 0x0F, 1) )
296
    ( tvrx2_tda18272_freq_map_t(218112000, 0x4F, 0x0F, 1) )
297
    ( tvrx2_tda18272_freq_map_t(219136000, 0x4E, 0x0F, 1) )
298
    ( tvrx2_tda18272_freq_map_t(220160000, 0x4D, 0x0E, 1) )
299
    ( tvrx2_tda18272_freq_map_t(221184000, 0x4C, 0x0E, 1) )
300
    ( tvrx2_tda18272_freq_map_t(222208000, 0x4B, 0x0E, 1) )
301
    ( tvrx2_tda18272_freq_map_t(223232000, 0x4A, 0x0E, 1) )
302
    ( tvrx2_tda18272_freq_map_t(224256000, 0x49, 0x0D, 1) )
303
    ( tvrx2_tda18272_freq_map_t(225280000, 0x48, 0x0D, 1) )
304
    ( tvrx2_tda18272_freq_map_t(226304000, 0x47, 0x0D, 1) )
305
    ( tvrx2_tda18272_freq_map_t(227328000, 0x46, 0x0D, 1) )
306
    ( tvrx2_tda18272_freq_map_t(228352000, 0x45, 0x0C, 1) )
307
    ( tvrx2_tda18272_freq_map_t(229376000, 0x44, 0x0C, 1) )
308
    ( tvrx2_tda18272_freq_map_t(230400000, 0x43, 0x0C, 1) )
309
    ( tvrx2_tda18272_freq_map_t(231424000, 0x42, 0x0C, 1) )
310
    ( tvrx2_tda18272_freq_map_t(232448000, 0x42, 0x0B, 1) )
311
    ( tvrx2_tda18272_freq_map_t(233472000, 0x41, 0x0B, 1) )
312
    ( tvrx2_tda18272_freq_map_t(234496000, 0x40, 0x0B, 1) )
313
    ( tvrx2_tda18272_freq_map_t(234496000, 0x3F, 0x0B, 1) )
314
    ( tvrx2_tda18272_freq_map_t(235520000, 0x3E, 0x0B, 1) )
315
    ( tvrx2_tda18272_freq_map_t(236544000, 0x3D, 0x0B, 1) )
316
    ( tvrx2_tda18272_freq_map_t(237568000, 0x3C, 0x0B, 1) )
317
    ( tvrx2_tda18272_freq_map_t(239616000, 0x3B, 0x0A, 1) )
318
    ( tvrx2_tda18272_freq_map_t(240640000, 0x3A, 0x0A, 1) )
319
    ( tvrx2_tda18272_freq_map_t(241664000, 0x39, 0x0A, 1) )
320
    ( tvrx2_tda18272_freq_map_t(242688000, 0x38, 0x0A, 1) )
321
    ( tvrx2_tda18272_freq_map_t(244736000, 0x37, 0x09, 1) )
322
    ( tvrx2_tda18272_freq_map_t(245760000, 0x36, 0x09, 1) )
323
    ( tvrx2_tda18272_freq_map_t(246784000, 0x35, 0x09, 1) )
324
    ( tvrx2_tda18272_freq_map_t(248832000, 0x34, 0x09, 1) )
325
    ( tvrx2_tda18272_freq_map_t(249856000, 0x33, 0x09, 1) )
326
    ( tvrx2_tda18272_freq_map_t(250880000, 0x32, 0x08, 1) )
327
    ( tvrx2_tda18272_freq_map_t(252928000, 0x31, 0x08, 1) )
328
    ( tvrx2_tda18272_freq_map_t(253952000, 0x30, 0x08, 1) )
329
    ( tvrx2_tda18272_freq_map_t(256000000, 0x2F, 0x08, 1) )
330
    ( tvrx2_tda18272_freq_map_t(257024000, 0x2E, 0x08, 1) )
331
    ( tvrx2_tda18272_freq_map_t(259072000, 0x2D, 0x07, 1) )
332
    ( tvrx2_tda18272_freq_map_t(260096000, 0x2C, 0x07, 1) )
333
    ( tvrx2_tda18272_freq_map_t(262144000, 0x2B, 0x07, 1) )
334
    ( tvrx2_tda18272_freq_map_t(264192000, 0x2A, 0x07, 1) )
335
    ( tvrx2_tda18272_freq_map_t(265216000, 0x29, 0x07, 1) )
336
    ( tvrx2_tda18272_freq_map_t(267264000, 0x28, 0x07, 1) )
337
    ( tvrx2_tda18272_freq_map_t(269312000, 0x27, 0x07, 1) )
338
    ( tvrx2_tda18272_freq_map_t(270336000, 0x26, 0x07, 1) )
339
    ( tvrx2_tda18272_freq_map_t(272384000, 0x25, 0x07, 1) )
340
    ( tvrx2_tda18272_freq_map_t(274432000, 0x24, 0x07, 1) )
341
    ( tvrx2_tda18272_freq_map_t(276480000, 0x23, 0x07, 1) )
342
    ( tvrx2_tda18272_freq_map_t(277504000, 0x22, 0x07, 1) )
343
    ( tvrx2_tda18272_freq_map_t(279552000, 0x21, 0x07, 1) )
344
    ( tvrx2_tda18272_freq_map_t(281600000, 0x20, 0x07, 1) )
345
    ( tvrx2_tda18272_freq_map_t(283648000, 0x1F, 0x07, 1) )
346
    ( tvrx2_tda18272_freq_map_t(285696000, 0x1E, 0x0F, 1) )
347
    ( tvrx2_tda18272_freq_map_t(287744000, 0x1D, 0x0F, 1) )
348
    ( tvrx2_tda18272_freq_map_t(289792000, 0x1C, 0x0E, 1) )
349
    ( tvrx2_tda18272_freq_map_t(291840000, 0x1B, 0x0E, 1) )
350
    ( tvrx2_tda18272_freq_map_t(293888000, 0x1A, 0x0D, 1) )
351
    ( tvrx2_tda18272_freq_map_t(296960000, 0x19, 0x0D, 1) )
352
    ( tvrx2_tda18272_freq_map_t(299008000, 0x18, 0x0C, 1) )
353
    ( tvrx2_tda18272_freq_map_t(301056000, 0x17, 0x0C, 1) )
354
    ( tvrx2_tda18272_freq_map_t(304128000, 0x16, 0x0C, 1) )
355
    ( tvrx2_tda18272_freq_map_t(306176000, 0x15, 0x0B, 1) )
356
    ( tvrx2_tda18272_freq_map_t(309248000, 0x14, 0x0B, 1) )
357
    ( tvrx2_tda18272_freq_map_t(312320000, 0x13, 0x0B, 1) )
358
    ( tvrx2_tda18272_freq_map_t(314368000, 0x12, 0x0B, 1) )
359
    ( tvrx2_tda18272_freq_map_t(317440000, 0x11, 0x0A, 1) )
360
    ( tvrx2_tda18272_freq_map_t(320512000, 0x10, 0x0A, 1) )
361
    ( tvrx2_tda18272_freq_map_t(322560000, 0x0F, 0x0A, 1) )
362
    ( tvrx2_tda18272_freq_map_t(325632000, 0x0E, 0x09, 1) )
363
    ( tvrx2_tda18272_freq_map_t(328704000, 0x0D, 0x09, 1) )
364
    ( tvrx2_tda18272_freq_map_t(331776000, 0x0C, 0x08, 1) )
365
    ( tvrx2_tda18272_freq_map_t(335872000, 0x0B, 0x08, 1) )
366
    ( tvrx2_tda18272_freq_map_t(338944000, 0x0A, 0x08, 1) )
367
    ( tvrx2_tda18272_freq_map_t(343040000, 0x09, 0x07, 1) )
368
    ( tvrx2_tda18272_freq_map_t(346112000, 0x08, 0x07, 1) )
369
    ( tvrx2_tda18272_freq_map_t(350208000, 0x07, 0x07, 1) )
370
    ( tvrx2_tda18272_freq_map_t(354304000, 0x06, 0x07, 1) )
371
    ( tvrx2_tda18272_freq_map_t(358400000, 0x05, 0x07, 1) )
372
    ( tvrx2_tda18272_freq_map_t(362496000, 0x04, 0x07, 1) )
373
    ( tvrx2_tda18272_freq_map_t(365568000, 0x04, 0x07, 1) )
374
    ( tvrx2_tda18272_freq_map_t(367616000, 0xDA, 0x2A, 2) )
375
    ( tvrx2_tda18272_freq_map_t(367616000, 0xD9, 0x27, 2) )
376
    ( tvrx2_tda18272_freq_map_t(368640000, 0xD8, 0x27, 2) )
377
    ( tvrx2_tda18272_freq_map_t(369664000, 0xD6, 0x27, 2) )
378
    ( tvrx2_tda18272_freq_map_t(370688000, 0xD5, 0x27, 2) )
379
    ( tvrx2_tda18272_freq_map_t(371712000, 0xD3, 0x25, 2) )
380
    ( tvrx2_tda18272_freq_map_t(372736000, 0xD2, 0x23, 2) )
381
    ( tvrx2_tda18272_freq_map_t(373760000, 0xD0, 0x23, 2) )
382
    ( tvrx2_tda18272_freq_map_t(374784000, 0xCF, 0x21, 2) )
383
    ( tvrx2_tda18272_freq_map_t(375808000, 0xCD, 0x1F, 2) )
384
    ( tvrx2_tda18272_freq_map_t(376832000, 0xCC, 0x1F, 2) )
385
    ( tvrx2_tda18272_freq_map_t(377856000, 0xCA, 0x1F, 2) )
386
    ( tvrx2_tda18272_freq_map_t(378880000, 0xC9, 0x1F, 2) )
387
    ( tvrx2_tda18272_freq_map_t(379904000, 0xC7, 0x1F, 2) )
388
    ( tvrx2_tda18272_freq_map_t(380928000, 0xC6, 0x1F, 2) )
389
    ( tvrx2_tda18272_freq_map_t(381952000, 0xC4, 0x1F, 2) )
390
    ( tvrx2_tda18272_freq_map_t(382976000, 0xC3, 0x1F, 2) )
391
    ( tvrx2_tda18272_freq_map_t(384000000, 0xC1, 0x1F, 2) )
392
    ( tvrx2_tda18272_freq_map_t(385024000, 0xC0, 0x1F, 2) )
393
    ( tvrx2_tda18272_freq_map_t(386048000, 0xBF, 0x1F, 2) )
394
    ( tvrx2_tda18272_freq_map_t(387072000, 0xBD, 0x1F, 2) )
395
    ( tvrx2_tda18272_freq_map_t(388096000, 0xBC, 0x1F, 2) )
396
    ( tvrx2_tda18272_freq_map_t(389120000, 0xBB, 0x1F, 2) )
397
    ( tvrx2_tda18272_freq_map_t(390144000, 0xB9, 0x1F, 2) )
398
    ( tvrx2_tda18272_freq_map_t(391168000, 0xB8, 0x1F, 2) )
399
    ( tvrx2_tda18272_freq_map_t(392192000, 0xB7, 0x1F, 2) )
400
    ( tvrx2_tda18272_freq_map_t(393216000, 0xB5, 0x1F, 2) )
401
    ( tvrx2_tda18272_freq_map_t(394240000, 0xB4, 0x1F, 2) )
402
    ( tvrx2_tda18272_freq_map_t(395264000, 0xB3, 0x1F, 2) )
403
    ( tvrx2_tda18272_freq_map_t(396288000, 0xB1, 0x1F, 2) )
404
    ( tvrx2_tda18272_freq_map_t(397312000, 0xB0, 0x1F, 2) )
405
    ( tvrx2_tda18272_freq_map_t(398336000, 0xAF, 0x1F, 2) )
406
    ( tvrx2_tda18272_freq_map_t(399360000, 0xAD, 0x1F, 2) )
407
    ( tvrx2_tda18272_freq_map_t(400384000, 0xAC, 0x1F, 2) )
408
    ( tvrx2_tda18272_freq_map_t(401408000, 0xAB, 0x1F, 2) )
409
    ( tvrx2_tda18272_freq_map_t(402432000, 0xAA, 0x1F, 2) )
410
    ( tvrx2_tda18272_freq_map_t(403456000, 0xA8, 0x1E, 2) )
411
    ( tvrx2_tda18272_freq_map_t(404480000, 0xA7, 0x1D, 2) )
412
    ( tvrx2_tda18272_freq_map_t(405504000, 0xA6, 0x1D, 2) )
413
    ( tvrx2_tda18272_freq_map_t(405504000, 0xA5, 0x1C, 2) )
414
    ( tvrx2_tda18272_freq_map_t(406528000, 0xA3, 0x1C, 2) )
415
    ( tvrx2_tda18272_freq_map_t(407552000, 0xA2, 0x1B, 2) )
416
    ( tvrx2_tda18272_freq_map_t(408576000, 0xA1, 0x1B, 2) )
417
    ( tvrx2_tda18272_freq_map_t(409600000, 0xA0, 0x1B, 2) )
418
    ( tvrx2_tda18272_freq_map_t(410624000, 0x9F, 0x1A, 2) )
419
    ( tvrx2_tda18272_freq_map_t(411648000, 0x9D, 0x1A, 2) )
420
    ( tvrx2_tda18272_freq_map_t(412672000, 0x9C, 0x19, 2) )
421
    ( tvrx2_tda18272_freq_map_t(413696000, 0x9B, 0x18, 2) )
422
    ( tvrx2_tda18272_freq_map_t(414720000, 0x9A, 0x18, 2) )
423
    ( tvrx2_tda18272_freq_map_t(415744000, 0x99, 0x17, 2) )
424
    ( tvrx2_tda18272_freq_map_t(416768000, 0x98, 0x17, 2) )
425
    ( tvrx2_tda18272_freq_map_t(417792000, 0x97, 0x17, 2) )
426
    ( tvrx2_tda18272_freq_map_t(418816000, 0x95, 0x17, 2) )
427
    ( tvrx2_tda18272_freq_map_t(419840000, 0x94, 0x17, 2) )
428
    ( tvrx2_tda18272_freq_map_t(420864000, 0x93, 0x17, 2) )
429
    ( tvrx2_tda18272_freq_map_t(421888000, 0x92, 0x17, 2) )
430
    ( tvrx2_tda18272_freq_map_t(422912000, 0x91, 0x17, 2) )
431
    ( tvrx2_tda18272_freq_map_t(423936000, 0x90, 0x17, 2) )
432
    ( tvrx2_tda18272_freq_map_t(424960000, 0x8F, 0x17, 2) )
433
    ( tvrx2_tda18272_freq_map_t(425984000, 0x8E, 0x16, 2) )
434
    ( tvrx2_tda18272_freq_map_t(427008000, 0x8D, 0x16, 2) )
435
    ( tvrx2_tda18272_freq_map_t(428032000, 0x8C, 0x15, 2) )
436
    ( tvrx2_tda18272_freq_map_t(429056000, 0x8B, 0x15, 2) )
437
    ( tvrx2_tda18272_freq_map_t(430080000, 0x8A, 0x15, 2) )
438
    ( tvrx2_tda18272_freq_map_t(431104000, 0x88, 0x14, 2) )
439
    ( tvrx2_tda18272_freq_map_t(432128000, 0x87, 0x14, 2) )
440
    ( tvrx2_tda18272_freq_map_t(433152000, 0x86, 0x14, 2) )
441
    ( tvrx2_tda18272_freq_map_t(434176000, 0x85, 0x13, 2) )
442
    ( tvrx2_tda18272_freq_map_t(435200000, 0x84, 0x13, 2) )
443
    ( tvrx2_tda18272_freq_map_t(436224000, 0x83, 0x13, 2) )
444
    ( tvrx2_tda18272_freq_map_t(437248000, 0x82, 0x13, 2) )
445
    ( tvrx2_tda18272_freq_map_t(438272000, 0x81, 0x13, 2) )
446
    ( tvrx2_tda18272_freq_map_t(439296000, 0x80, 0x12, 2) )
447
    ( tvrx2_tda18272_freq_map_t(440320000, 0x7F, 0x12, 2) )
448
    ( tvrx2_tda18272_freq_map_t(441344000, 0x7E, 0x12, 2) )
449
    ( tvrx2_tda18272_freq_map_t(442368000, 0x7D, 0x11, 2) )
450
    ( tvrx2_tda18272_freq_map_t(444416000, 0x7C, 0x11, 2) )
451
    ( tvrx2_tda18272_freq_map_t(445440000, 0x7B, 0x10, 2) )
452
    ( tvrx2_tda18272_freq_map_t(446464000, 0x7A, 0x10, 2) )
453
    ( tvrx2_tda18272_freq_map_t(447488000, 0x79, 0x10, 2) )
454
    ( tvrx2_tda18272_freq_map_t(448512000, 0x78, 0x10, 2) )
455
    ( tvrx2_tda18272_freq_map_t(448512000, 0x77, 0x0F, 2) )
456
    ( tvrx2_tda18272_freq_map_t(449536000, 0x76, 0x0F, 2) )
457
    ( tvrx2_tda18272_freq_map_t(450560000, 0x75, 0x0F, 2) )
458
    ( tvrx2_tda18272_freq_map_t(451584000, 0x74, 0x0F, 2) )
459
    ( tvrx2_tda18272_freq_map_t(452608000, 0x73, 0x0F, 2) )
460
    ( tvrx2_tda18272_freq_map_t(453632000, 0x72, 0x0F, 2) )
461
    ( tvrx2_tda18272_freq_map_t(454656000, 0x71, 0x0F, 2) )
462
    ( tvrx2_tda18272_freq_map_t(455680000, 0x70, 0x0F, 2) )
463
    ( tvrx2_tda18272_freq_map_t(457728000, 0x6F, 0x0F, 2) )
464
    ( tvrx2_tda18272_freq_map_t(458752000, 0x6E, 0x0F, 2) )
465
    ( tvrx2_tda18272_freq_map_t(459776000, 0x6D, 0x0F, 2) )
466
    ( tvrx2_tda18272_freq_map_t(460800000, 0x6C, 0x0F, 2) )
467
    ( tvrx2_tda18272_freq_map_t(461824000, 0x6B, 0x0F, 2) )
468
    ( tvrx2_tda18272_freq_map_t(462848000, 0x6A, 0x0F, 2) )
469
    ( tvrx2_tda18272_freq_map_t(464896000, 0x69, 0x0F, 2) )
470
    ( tvrx2_tda18272_freq_map_t(465920000, 0x68, 0x0F, 2) )
471
    ( tvrx2_tda18272_freq_map_t(466944000, 0x67, 0x0F, 2) )
472
    ( tvrx2_tda18272_freq_map_t(467968000, 0x66, 0x0F, 2) )
473
    ( tvrx2_tda18272_freq_map_t(468992000, 0x65, 0x0F, 2) )
474
    ( tvrx2_tda18272_freq_map_t(471040000, 0x64, 0x0F, 2) )
475
    ( tvrx2_tda18272_freq_map_t(472064000, 0x63, 0x0F, 2) )
476
    ( tvrx2_tda18272_freq_map_t(473088000, 0x62, 0x0F, 2) )
477
    ( tvrx2_tda18272_freq_map_t(474112000, 0x61, 0x0F, 2) )
478
    ( tvrx2_tda18272_freq_map_t(476160000, 0x60, 0x0F, 2) )
479
    ( tvrx2_tda18272_freq_map_t(477184000, 0x5F, 0x0F, 2) )
480
    ( tvrx2_tda18272_freq_map_t(478208000, 0x5E, 0x0F, 2) )
481
    ( tvrx2_tda18272_freq_map_t(479232000, 0x5D, 0x0F, 2) )
482
    ( tvrx2_tda18272_freq_map_t(481280000, 0x5C, 0x0F, 2) )
483
    ( tvrx2_tda18272_freq_map_t(482304000, 0x5B, 0x0F, 2) )
484
    ( tvrx2_tda18272_freq_map_t(483328000, 0x5A, 0x0F, 2) )
485
    ( tvrx2_tda18272_freq_map_t(485376000, 0x59, 0x0F, 2) )
486
    ( tvrx2_tda18272_freq_map_t(486400000, 0x58, 0x0F, 2) )
487
    ( tvrx2_tda18272_freq_map_t(487424000, 0x57, 0x0F, 2) )
488
    ( tvrx2_tda18272_freq_map_t(489472000, 0x56, 0x0F, 2) )
489
    ( tvrx2_tda18272_freq_map_t(490496000, 0x55, 0x0F, 2) )
490
    ( tvrx2_tda18272_freq_map_t(490496000, 0x54, 0x0F, 2) )
491
    ( tvrx2_tda18272_freq_map_t(492544000, 0x53, 0x0E, 2) )
492
    ( tvrx2_tda18272_freq_map_t(493568000, 0x52, 0x0E, 2) )
493
    ( tvrx2_tda18272_freq_map_t(495616000, 0x51, 0x0E, 2) )
494
    ( tvrx2_tda18272_freq_map_t(496640000, 0x50, 0x0E, 2) )
495
    ( tvrx2_tda18272_freq_map_t(497664000, 0x4F, 0x0E, 2) )
496
    ( tvrx2_tda18272_freq_map_t(499712000, 0x4E, 0x0D, 2) )
497
    ( tvrx2_tda18272_freq_map_t(500736000, 0x4D, 0x0D, 2) )
498
    ( tvrx2_tda18272_freq_map_t(502784000, 0x4C, 0x0D, 2) )
499
    ( tvrx2_tda18272_freq_map_t(503808000, 0x4B, 0x0D, 2) )
500
    ( tvrx2_tda18272_freq_map_t(505856000, 0x4A, 0x0C, 2) )
501
    ( tvrx2_tda18272_freq_map_t(506880000, 0x49, 0x0C, 2) )
502
    ( tvrx2_tda18272_freq_map_t(508928000, 0x48, 0x0C, 2) )
503
    ( tvrx2_tda18272_freq_map_t(509952000, 0x47, 0x0C, 2) )
504
    ( tvrx2_tda18272_freq_map_t(512000000, 0x46, 0x0C, 2) )
505
    ( tvrx2_tda18272_freq_map_t(513024000, 0x45, 0x0B, 2) )
506
    ( tvrx2_tda18272_freq_map_t(515072000, 0x44, 0x0B, 2) )
507
    ( tvrx2_tda18272_freq_map_t(517120000, 0x43, 0x0B, 2) )
508
    ( tvrx2_tda18272_freq_map_t(518144000, 0x42, 0x0B, 2) )
509
    ( tvrx2_tda18272_freq_map_t(520192000, 0x41, 0x0B, 2) )
510
    ( tvrx2_tda18272_freq_map_t(521216000, 0x40, 0x0B, 2) )
511
    ( tvrx2_tda18272_freq_map_t(523264000, 0x3F, 0x0B, 2) )
512
    ( tvrx2_tda18272_freq_map_t(525312000, 0x3E, 0x0B, 2) )
513
    ( tvrx2_tda18272_freq_map_t(526336000, 0x3D, 0x0B, 2) )
514
    ( tvrx2_tda18272_freq_map_t(528384000, 0x3C, 0x0A, 2) )
515
    ( tvrx2_tda18272_freq_map_t(530432000, 0x3B, 0x0A, 2) )
516
    ( tvrx2_tda18272_freq_map_t(531456000, 0x3A, 0x0A, 2) )
517
    ( tvrx2_tda18272_freq_map_t(533504000, 0x39, 0x0A, 2) )
518
    ( tvrx2_tda18272_freq_map_t(534528000, 0x38, 0x0A, 2) )
519
    ( tvrx2_tda18272_freq_map_t(536576000, 0x37, 0x0A, 2) )
520
    ( tvrx2_tda18272_freq_map_t(537600000, 0x36, 0x09, 2) )
521
    ( tvrx2_tda18272_freq_map_t(539648000, 0x35, 0x09, 2) )
522
    ( tvrx2_tda18272_freq_map_t(541696000, 0x34, 0x09, 2) )
523
    ( tvrx2_tda18272_freq_map_t(543744000, 0x33, 0x09, 2) )
524
    ( tvrx2_tda18272_freq_map_t(544768000, 0x32, 0x09, 2) )
525
    ( tvrx2_tda18272_freq_map_t(546816000, 0x31, 0x09, 2) )
526
    ( tvrx2_tda18272_freq_map_t(548864000, 0x30, 0x08, 2) )
527
    ( tvrx2_tda18272_freq_map_t(550912000, 0x2F, 0x08, 2) )
528
    ( tvrx2_tda18272_freq_map_t(552960000, 0x2E, 0x08, 2) )
529
    ( tvrx2_tda18272_freq_map_t(555008000, 0x2D, 0x08, 2) )
530
    ( tvrx2_tda18272_freq_map_t(557056000, 0x2C, 0x08, 2) )
531
    ( tvrx2_tda18272_freq_map_t(559104000, 0x2B, 0x08, 2) )
532
    ( tvrx2_tda18272_freq_map_t(561152000, 0x2A, 0x07, 2) )
533
    ( tvrx2_tda18272_freq_map_t(563200000, 0x29, 0x07, 2) )
534
    ( tvrx2_tda18272_freq_map_t(565248000, 0x28, 0x07, 2) )
535
    ( tvrx2_tda18272_freq_map_t(567296000, 0x27, 0x07, 2) )
536
    ( tvrx2_tda18272_freq_map_t(569344000, 0x26, 0x07, 2) )
537
    ( tvrx2_tda18272_freq_map_t(570368000, 0x26, 0x07, 2) )
538
    ( tvrx2_tda18272_freq_map_t(571392000, 0x25, 0x07, 2) )
539
    ( tvrx2_tda18272_freq_map_t(573440000, 0x24, 0x07, 2) )
540
    ( tvrx2_tda18272_freq_map_t(575488000, 0x23, 0x07, 2) )
541
    ( tvrx2_tda18272_freq_map_t(577536000, 0x22, 0x0F, 2) )
542
    ( tvrx2_tda18272_freq_map_t(578560000, 0x21, 0x0F, 2) )
543
    ( tvrx2_tda18272_freq_map_t(580608000, 0x20, 0x0F, 2) )
544
    ( tvrx2_tda18272_freq_map_t(583680000, 0x1F, 0x0F, 2) )
545
    ( tvrx2_tda18272_freq_map_t(585728000, 0x1E, 0x0F, 2) )
546
    ( tvrx2_tda18272_freq_map_t(587776000, 0x1D, 0x0F, 2) )
547
    ( tvrx2_tda18272_freq_map_t(589824000, 0x1C, 0x0F, 2) )
548
    ( tvrx2_tda18272_freq_map_t(592896000, 0x1B, 0x0F, 2) )
549
    ( tvrx2_tda18272_freq_map_t(594944000, 0x1A, 0x0F, 2) )
550
    ( tvrx2_tda18272_freq_map_t(596992000, 0x19, 0x0F, 2) )
551
    ( tvrx2_tda18272_freq_map_t(600064000, 0x18, 0x0F, 2) )
552
    ( tvrx2_tda18272_freq_map_t(602112000, 0x17, 0x0F, 2) )
553
    ( tvrx2_tda18272_freq_map_t(604160000, 0x16, 0x0F, 2) )
554
    ( tvrx2_tda18272_freq_map_t(607232000, 0x15, 0x0F, 2) )
555
    ( tvrx2_tda18272_freq_map_t(609280000, 0x14, 0x0F, 2) )
556
    ( tvrx2_tda18272_freq_map_t(612352000, 0x13, 0x0F, 2) )
557
    ( tvrx2_tda18272_freq_map_t(615424000, 0x12, 0x0F, 2) )
558
    ( tvrx2_tda18272_freq_map_t(617472000, 0x11, 0x0F, 2) )
559
    ( tvrx2_tda18272_freq_map_t(619520000, 0x10, 0x0E, 2) )
560
    ( tvrx2_tda18272_freq_map_t(621568000, 0x0F, 0x0E, 2) )
561
    ( tvrx2_tda18272_freq_map_t(623616000, 0x0F, 0x0E, 2) )
562
    ( tvrx2_tda18272_freq_map_t(624640000, 0xA3, 0x1F, 3) )
563
    ( tvrx2_tda18272_freq_map_t(625664000, 0xA2, 0x1F, 3) )
564
    ( tvrx2_tda18272_freq_map_t(626688000, 0xA1, 0x1F, 3) )
565
    ( tvrx2_tda18272_freq_map_t(627712000, 0xA0, 0x1F, 3) )
566
    ( tvrx2_tda18272_freq_map_t(628736000, 0x9F, 0x1F, 3) )
567
    ( tvrx2_tda18272_freq_map_t(630784000, 0x9E, 0x1F, 3) )
568
    ( tvrx2_tda18272_freq_map_t(631808000, 0x9D, 0x1F, 3) )
569
    ( tvrx2_tda18272_freq_map_t(632832000, 0x9C, 0x1F, 3) )
570
    ( tvrx2_tda18272_freq_map_t(633856000, 0x9B, 0x1F, 3) )
571
    ( tvrx2_tda18272_freq_map_t(635904000, 0x9A, 0x1F, 3) )
572
    ( tvrx2_tda18272_freq_map_t(636928000, 0x99, 0x1F, 3) )
573
    ( tvrx2_tda18272_freq_map_t(637952000, 0x98, 0x1F, 3) )
574
    ( tvrx2_tda18272_freq_map_t(638976000, 0x97, 0x1F, 3) )
575
    ( tvrx2_tda18272_freq_map_t(641024000, 0x96, 0x1E, 3) )
576
    ( tvrx2_tda18272_freq_map_t(642048000, 0x95, 0x1E, 3) )
577
    ( tvrx2_tda18272_freq_map_t(643072000, 0x94, 0x1E, 3) )
578
    ( tvrx2_tda18272_freq_map_t(644096000, 0x93, 0x1D, 3) )
579
    ( tvrx2_tda18272_freq_map_t(646144000, 0x92, 0x1D, 3) )
580
    ( tvrx2_tda18272_freq_map_t(647168000, 0x91, 0x1C, 3) )
581
    ( tvrx2_tda18272_freq_map_t(648192000, 0x90, 0x1C, 3) )
582
    ( tvrx2_tda18272_freq_map_t(650240000, 0x8F, 0x1B, 3) )
583
    ( tvrx2_tda18272_freq_map_t(651264000, 0x8E, 0x1B, 3) )
584
    ( tvrx2_tda18272_freq_map_t(652288000, 0x8D, 0x1B, 3) )
585
    ( tvrx2_tda18272_freq_map_t(654336000, 0x8C, 0x1B, 3) )
586
    ( tvrx2_tda18272_freq_map_t(655360000, 0x8B, 0x1B, 3) )
587
    ( tvrx2_tda18272_freq_map_t(656384000, 0x8A, 0x1B, 3) )
588
    ( tvrx2_tda18272_freq_map_t(658432000, 0x89, 0x1A, 3) )
589
    ( tvrx2_tda18272_freq_map_t(659456000, 0x88, 0x1A, 3) )
590
    ( tvrx2_tda18272_freq_map_t(660480000, 0x87, 0x1A, 3) )
591
    ( tvrx2_tda18272_freq_map_t(661504000, 0x86, 0x19, 3) )
592
    ( tvrx2_tda18272_freq_map_t(662528000, 0x85, 0x19, 3) )
593
    ( tvrx2_tda18272_freq_map_t(664576000, 0x84, 0x18, 3) )
594
    ( tvrx2_tda18272_freq_map_t(665600000, 0x83, 0x18, 3) )
595
    ( tvrx2_tda18272_freq_map_t(666624000, 0x82, 0x18, 3) )
596
    ( tvrx2_tda18272_freq_map_t(668672000, 0x81, 0x18, 3) )
597
    ( tvrx2_tda18272_freq_map_t(669696000, 0x80, 0x17, 3) )
598
    ( tvrx2_tda18272_freq_map_t(671744000, 0x7F, 0x17, 3) )
599
    ( tvrx2_tda18272_freq_map_t(672768000, 0x7E, 0x17, 3) )
600
    ( tvrx2_tda18272_freq_map_t(674816000, 0x7D, 0x17, 3) )
601
    ( tvrx2_tda18272_freq_map_t(675840000, 0x7C, 0x17, 3) )
602
    ( tvrx2_tda18272_freq_map_t(676864000, 0x7B, 0x17, 3) )
603
    ( tvrx2_tda18272_freq_map_t(678912000, 0x7A, 0x17, 3) )
604
    ( tvrx2_tda18272_freq_map_t(679936000, 0x79, 0x17, 3) )
605
    ( tvrx2_tda18272_freq_map_t(681984000, 0x78, 0x17, 3) )
606
    ( tvrx2_tda18272_freq_map_t(683008000, 0x77, 0x17, 3) )
607
    ( tvrx2_tda18272_freq_map_t(685056000, 0x76, 0x17, 3) )
608
    ( tvrx2_tda18272_freq_map_t(686080000, 0x75, 0x17, 3) )
609
    ( tvrx2_tda18272_freq_map_t(688128000, 0x74, 0x17, 3) )
610
    ( tvrx2_tda18272_freq_map_t(689152000, 0x73, 0x17, 3) )
611
    ( tvrx2_tda18272_freq_map_t(691200000, 0x72, 0x16, 3) )
612
    ( tvrx2_tda18272_freq_map_t(693248000, 0x71, 0x16, 3) )
613
    ( tvrx2_tda18272_freq_map_t(694272000, 0x70, 0x16, 3) )
614
    ( tvrx2_tda18272_freq_map_t(696320000, 0x6F, 0x15, 3) )
615
    ( tvrx2_tda18272_freq_map_t(697344000, 0x6E, 0x15, 3) )
616
    ( tvrx2_tda18272_freq_map_t(699392000, 0x6D, 0x15, 3) )
617
    ( tvrx2_tda18272_freq_map_t(700416000, 0x6C, 0x15, 3) )
618
    ( tvrx2_tda18272_freq_map_t(702464000, 0x6B, 0x14, 3) )
619
    ( tvrx2_tda18272_freq_map_t(704512000, 0x6A, 0x14, 3) )
620
    ( tvrx2_tda18272_freq_map_t(704512000, 0x69, 0x14, 3) )
621
    ( tvrx2_tda18272_freq_map_t(706560000, 0x68, 0x14, 3) )
622
    ( tvrx2_tda18272_freq_map_t(707584000, 0x67, 0x13, 3) )
623
    ( tvrx2_tda18272_freq_map_t(709632000, 0x66, 0x13, 3) )
624
    ( tvrx2_tda18272_freq_map_t(711680000, 0x65, 0x13, 3) )
625
    ( tvrx2_tda18272_freq_map_t(712704000, 0x64, 0x13, 3) )
626
    ( tvrx2_tda18272_freq_map_t(714752000, 0x63, 0x13, 3) )
627
    ( tvrx2_tda18272_freq_map_t(716800000, 0x62, 0x13, 3) )
628
    ( tvrx2_tda18272_freq_map_t(717824000, 0x61, 0x13, 3) )
629
    ( tvrx2_tda18272_freq_map_t(719872000, 0x60, 0x13, 3) )
630
    ( tvrx2_tda18272_freq_map_t(721920000, 0x5F, 0x12, 3) )
631
    ( tvrx2_tda18272_freq_map_t(723968000, 0x5E, 0x12, 3) )
632
    ( tvrx2_tda18272_freq_map_t(724992000, 0x5D, 0x12, 3) )
633
    ( tvrx2_tda18272_freq_map_t(727040000, 0x5C, 0x12, 3) )
634
    ( tvrx2_tda18272_freq_map_t(729088000, 0x5B, 0x11, 3) )
635
    ( tvrx2_tda18272_freq_map_t(731136000, 0x5A, 0x11, 3) )
636
    ( tvrx2_tda18272_freq_map_t(732160000, 0x59, 0x11, 3) )
637
    ( tvrx2_tda18272_freq_map_t(734208000, 0x58, 0x11, 3) )
638
    ( tvrx2_tda18272_freq_map_t(736256000, 0x57, 0x10, 3) )
639
    ( tvrx2_tda18272_freq_map_t(738304000, 0x56, 0x10, 3) )
640
    ( tvrx2_tda18272_freq_map_t(740352000, 0x55, 0x10, 3) )
641
    ( tvrx2_tda18272_freq_map_t(741376000, 0x54, 0x10, 3) )
642
    ( tvrx2_tda18272_freq_map_t(743424000, 0x53, 0x10, 3) )
643
    ( tvrx2_tda18272_freq_map_t(745472000, 0x52, 0x0F, 3) )
644
    ( tvrx2_tda18272_freq_map_t(746496000, 0x51, 0x0F, 3) )
645
    ( tvrx2_tda18272_freq_map_t(748544000, 0x50, 0x0F, 3) )
646
    ( tvrx2_tda18272_freq_map_t(750592000, 0x4F, 0x0F, 3) )
647
    ( tvrx2_tda18272_freq_map_t(752640000, 0x4E, 0x0F, 3) )
648
    ( tvrx2_tda18272_freq_map_t(753664000, 0x4D, 0x0F, 3) )
649
    ( tvrx2_tda18272_freq_map_t(755712000, 0x4C, 0x0F, 3) )
650
    ( tvrx2_tda18272_freq_map_t(757760000, 0x4B, 0x0F, 3) )
651
    ( tvrx2_tda18272_freq_map_t(759808000, 0x4A, 0x0F, 3) )
652
    ( tvrx2_tda18272_freq_map_t(761856000, 0x49, 0x0F, 3) )
653
    ( tvrx2_tda18272_freq_map_t(762880000, 0x49, 0x0F, 3) )
654
    ( tvrx2_tda18272_freq_map_t(763904000, 0x48, 0x0F, 3) )
655
    ( tvrx2_tda18272_freq_map_t(765952000, 0x47, 0x0F, 3) )
656
    ( tvrx2_tda18272_freq_map_t(768000000, 0x46, 0x0F, 3) )
657
    ( tvrx2_tda18272_freq_map_t(770048000, 0x45, 0x0F, 3) )
658
    ( tvrx2_tda18272_freq_map_t(772096000, 0x44, 0x0F, 3) )
659
    ( tvrx2_tda18272_freq_map_t(774144000, 0x43, 0x0F, 3) )
660
    ( tvrx2_tda18272_freq_map_t(776192000, 0x42, 0x0F, 3) )
661
    ( tvrx2_tda18272_freq_map_t(778240000, 0x41, 0x0F, 3) )
662
    ( tvrx2_tda18272_freq_map_t(780288000, 0x40, 0x0F, 3) )
663
    ( tvrx2_tda18272_freq_map_t(783360000, 0x3F, 0x0F, 3) )
664
    ( tvrx2_tda18272_freq_map_t(785408000, 0x3E, 0x0F, 3) )
665
    ( tvrx2_tda18272_freq_map_t(787456000, 0x3D, 0x0F, 3) )
666
    ( tvrx2_tda18272_freq_map_t(789504000, 0x3C, 0x0F, 3) )
667
    ( tvrx2_tda18272_freq_map_t(790528000, 0x3B, 0x0F, 3) )
668
    ( tvrx2_tda18272_freq_map_t(792576000, 0x3A, 0x0F, 3) )
669
    ( tvrx2_tda18272_freq_map_t(794624000, 0x39, 0x0F, 3) )
670
    ( tvrx2_tda18272_freq_map_t(797696000, 0x38, 0x0F, 3) )
671
    ( tvrx2_tda18272_freq_map_t(799744000, 0x37, 0x0F, 3) )
672
    ( tvrx2_tda18272_freq_map_t(801792000, 0x36, 0x0F, 3) )
673
    ( tvrx2_tda18272_freq_map_t(803840000, 0x35, 0x0F, 3) )
674
    ( tvrx2_tda18272_freq_map_t(806912000, 0x34, 0x0F, 3) )
675
    ( tvrx2_tda18272_freq_map_t(808960000, 0x33, 0x0F, 3) )
676
    ( tvrx2_tda18272_freq_map_t(809984000, 0x33, 0x0F, 3) )
677
    ( tvrx2_tda18272_freq_map_t(811008000, 0x32, 0x0F, 3) )
678
    ( tvrx2_tda18272_freq_map_t(813056000, 0x31, 0x0F, 3) )
679
    ( tvrx2_tda18272_freq_map_t(816128000, 0x30, 0x0F, 3) )
680
    ( tvrx2_tda18272_freq_map_t(818176000, 0x2F, 0x0F, 3) )
681
    ( tvrx2_tda18272_freq_map_t(820224000, 0x2E, 0x0F, 3) )
682
    ( tvrx2_tda18272_freq_map_t(823296000, 0x2D, 0x0F, 3) )
683
    ( tvrx2_tda18272_freq_map_t(825344000, 0x2C, 0x0F, 3) )
684
    ( tvrx2_tda18272_freq_map_t(828416000, 0x2B, 0x0F, 3) )
685
    ( tvrx2_tda18272_freq_map_t(830464000, 0x2A, 0x0F, 3) )
686
    ( tvrx2_tda18272_freq_map_t(832512000, 0x29, 0x0F, 3) )
687
    ( tvrx2_tda18272_freq_map_t(834560000, 0x28, 0x0F, 3) )
688
    ( tvrx2_tda18272_freq_map_t(836608000, 0x27, 0x0F, 3) )
689
    ( tvrx2_tda18272_freq_map_t(839680000, 0x26, 0x0F, 3) )
690
    ( tvrx2_tda18272_freq_map_t(841728000, 0x25, 0x0F, 3) )
691
    ( tvrx2_tda18272_freq_map_t(844800000, 0x24, 0x0F, 3) )
692
    ( tvrx2_tda18272_freq_map_t(847872000, 0x23, 0x0F, 3) )
693
    ( tvrx2_tda18272_freq_map_t(849920000, 0x22, 0x0F, 3) )
694
    ( tvrx2_tda18272_freq_map_t(852992000, 0x21, 0x0E, 3) )
695
    ( tvrx2_tda18272_freq_map_t(855040000, 0x20, 0x0E, 3) )
696
    ( tvrx2_tda18272_freq_map_t(858112000, 0x1F, 0x0E, 3) )
697
    ( tvrx2_tda18272_freq_map_t(861184000, 0x1E, 0x0E, 3) )
698
    ( tvrx2_tda18272_freq_map_t(863232000, 0x1D, 0x0E, 3) )
699
    ( tvrx2_tda18272_freq_map_t(866304000, 0x1C, 0x0E, 3) )
700
    ( tvrx2_tda18272_freq_map_t(900096000, 0x10, 0x0C, 3) )
701
    ( tvrx2_tda18272_freq_map_t(929792000, 0x07, 0x0B, 3) )
702
    ( tvrx2_tda18272_freq_map_t(969728000, 0x00, 0x0A, 3) )
703
;
704

    
705
static const freq_range_t tvrx2_freq_range(42e6, 870e6);
706

    
707
static const uhd::dict<std::string, std::string> tvrx2_sd_name_to_antennas = map_list_of
708
    ("RX1", "J100")
709
    ("RX2", "J140")
710
;
711

    
712
static const uhd::dict<std::string, subdev_conn_t> tvrx2_sd_name_to_conn = map_list_of
713
    ("RX1",  SUBDEV_CONN_REAL_Q)
714
    ("RX2",  SUBDEV_CONN_REAL_I)
715
;
716

    
717
static const uhd::dict<std::string, boost::uint8_t> tvrx2_sd_name_to_i2c_addr = map_list_of
718
    ("RX1", 0x63)
719
    ("RX2", 0x60)
720
;
721

    
722
static const uhd::dict<std::string, boost::uint8_t> tvrx2_sd_name_to_irq_io = map_list_of
723
    ("RX1", (RX1_IRQ))
724
    ("RX2", (RX2_IRQ))
725
;
726

    
727
static const uhd::dict<std::string, dboard_iface::aux_dac_t> tvrx2_sd_name_to_dac = map_list_of
728
    ("RX1", dboard_iface::AUX_DAC_A)
729
    ("RX2", dboard_iface::AUX_DAC_B)
730
;
731

    
732
static const uhd::dict<std::string, gain_range_t> tvrx2_gain_ranges = map_list_of
733
//    ("LNA", gain_range_t(-12, 15, 3))
734
//    ("RF_FILTER", gain_range_t(-11, -2, 3))
735
//    ("IR_MIXER", gain_range_t(2, 14, 3))
736
//    ("LPF", gain_range_t(0, 9, 3))
737
    ("IF", gain_range_t(0, 30, 0.5))
738
;
739

    
740
/***********************************************************************
741
 * The TVRX2 dboard class
742
 **********************************************************************/
743
class tvrx2 : public rx_dboard_base{
744
public:
745
    tvrx2(ctor_args_t args);
746
    ~tvrx2(void);
747

    
748
    void rx_get(const wax::obj &key, wax::obj &val);
749
    void rx_set(const wax::obj &key, const wax::obj &val);
750

    
751
private:
752
    double _freq_scalar;
753
    double _lo_freq;
754
    double _if_freq;
755
    double _bandwidth;
756
    uhd::dict<std::string, double> _gains;
757
    tda18272hnm_regs_t _tda18272hnm_regs;
758
    uhd::dict<boost::uint32_t, tvrx2_tda18272_rfcal_result_t> _rfcal_results;
759
    uhd::dict<boost::uint32_t, tvrx2_tda18272_rfcal_coeffs_t> _rfcal_coeffs;
760

    
761
    bool _enabled;
762

    
763
    void set_enabled(void);
764
    void set_disabled(void);
765

    
766
    void set_lo_freq(double target_freq);
767
    void set_gain(double gain, const std::string &name);
768
    void set_bandwidth(double bandwidth);
769

    
770
    void set_scaled_rf_freq(double rf_freq);
771
    double get_scaled_rf_freq(void);
772
    void set_scaled_if_freq(double if_freq);
773
    double get_scaled_if_freq(void);
774
    void send_reg(boost::uint8_t start_reg, boost::uint8_t stop_reg);
775
    void read_reg(boost::uint8_t start_reg, boost::uint8_t stop_reg);
776

    
777
    freq_range_t get_tda18272_rfcal_result_freq_range(boost::uint32_t result);
778
    void tvrx2_tda18272_init_rfcal(void);
779
    void tvrx2_tda18272_tune_rf_filter(boost::uint32_t uRF);
780
    void soft_calibration(void);
781
    void transition_0(void);
782
    void transition_1(void);
783
    void transition_2(int rf_freq);
784
    void transition_3(void);
785
    void transition_4(int rf_freq);
786
    void wait_irq(void);
787
    void test_rf_filter_robustness(void);
788

    
789
/***********************************************************************
790
 * The TVRX2 class helper functions
791
 **********************************************************************/
792
    /*!
793
     * Is the IRQ set or cleared?
794
     * \return true for set
795
     */
796
    bool get_irq(void){
797
        read_reg(0x8, 0x8);
798

    
799
        //return irq status
800
        bool irq = _tda18272hnm_regs.irq_status == tda18272hnm_regs_t::IRQ_STATUS_SET;
801

    
802
        UHD_LOGV(often) << boost::format(
803
            "TVRX2 (%s): IRQ %d"
804
        ) % (get_subdev_name()) % irq << std::endl;
805

    
806
        return irq;
807
    }
808

    
809
    /*!
810
     * In Power-On Reset State?
811
     *      Check POR logic for reset state (causes POR to clear)
812
     * \return true for reset
813
     */
814
    bool get_power_reset(void){
815
        read_reg(0x5, 0x5);
816

    
817
        //return POR state
818
        bool por = _tda18272hnm_regs.por == tda18272hnm_regs_t::POR_RESET;
819

    
820
        UHD_LOGV(often) << boost::format(
821
            "TVRX2 (%s): POR %d"
822
        ) % (get_subdev_name()) % int(_tda18272hnm_regs.por) << std::endl;
823

    
824
        return por;
825
    }
826

    
827
    /*!
828
     * Is the LO locked?
829
     * \return true for locked
830
     */
831
    bool get_locked(void){
832
        read_reg(0x5, 0x5);
833

    
834
        //return lock detect
835
        bool locked = _tda18272hnm_regs.lo_lock == tda18272hnm_regs_t::LO_LOCK_LOCKED;
836

    
837
        UHD_LOGV(often) << boost::format(
838
            "TVRX2 (%s): locked %d"
839
        ) % (get_subdev_name()) % locked << std::endl;
840

    
841
        return locked;
842
    }
843

    
844
    /*!
845
     * Read the RSSI from the registers
846
     * \return the rssi in dB(m?) FIXME
847
     */
848
    double get_rssi(void){
849
        //Launch RSSI calculation with MSM statemachine
850
        _tda18272hnm_regs.set_reg(0x19, 0x80); //set MSM_byte_1 for rssi calculation
851
        _tda18272hnm_regs.set_reg(0x1A, 0x01); //set MSM_byte_2 for launching rssi calculation
852

    
853
        send_reg(0x19, 0x1A);
854

    
855
        wait_irq();
856

    
857
        //read rssi in dBuV
858
        read_reg(0x7, 0x7);
859

    
860
        //calculate the rssi from the voltage
861
        double rssi_dBuV = 40.0 + double(((110.0 - 40.0)/128.0) * _tda18272hnm_regs.get_reg(0x7));
862
        return rssi_dBuV - 107.0; //convert to dBm in 50ohm environment ( -108.8 if 75ohm ) FIXME
863
    }
864

    
865
    /*!
866
     * Read the Temperature from the registers
867
     * \return the temp in degC
868
     */
869
    double get_temp(void){
870
        //Enable Temperature reading
871
        _tda18272hnm_regs.tm_on = tda18272hnm_regs_t::TM_ON_SENSOR_ON;
872
        send_reg(0x4, 0x4);
873

    
874
        //read temp in degC
875
        read_reg(0x3, 0x3);
876

    
877
        UHD_LOGV(often) << boost::format(
878
            "TVRX2 (%s): Temperature %f C"
879
        ) % (get_subdev_name()) % (double(_tda18272hnm_regs.tm_d)) << std::endl;
880

    
881
        //Disable Temperature reading
882
        _tda18272hnm_regs.tm_on = tda18272hnm_regs_t::TM_ON_SENSOR_OFF;
883
        send_reg(0x4, 0x4);
884

    
885
        return (double(_tda18272hnm_regs.tm_d));
886
    }
887
};
888

    
889
/***********************************************************************
890
 * Register the TVRX2 dboard
891
 **********************************************************************/
892
static dboard_base::sptr make_tvrx2(dboard_base::ctor_args_t args){
893
    return dboard_base::sptr(new tvrx2(args));
894
}
895

    
896
UHD_STATIC_BLOCK(reg_tvrx2_dboard){
897
    //register the factory function for the rx dbid
898
    dboard_manager::register_dboard(0x0046, &make_tvrx2, "TVRX2", tvrx2_sd_name_to_conn.keys());
899
}
900

    
901
/***********************************************************************
902
 * Structors
903
 **********************************************************************/
904
tvrx2::tvrx2(ctor_args_t args) : rx_dboard_base(args){
905
    //FIXME for USRP1, we can only support one TVRX2 installed
906

    
907
    _rfcal_results = map_list_of
908
        (  0, tvrx2_tda18272_rfcal_result_t() )
909
        (  1, tvrx2_tda18272_rfcal_result_t() )
910
        (  2, tvrx2_tda18272_rfcal_result_t() )
911
        (  3, tvrx2_tda18272_rfcal_result_t() )
912
        (  4, tvrx2_tda18272_rfcal_result_t() )
913
        (  5, tvrx2_tda18272_rfcal_result_t() )
914
        (  6, tvrx2_tda18272_rfcal_result_t() )
915
        (  7, tvrx2_tda18272_rfcal_result_t() )
916
        (  8, tvrx2_tda18272_rfcal_result_t() )
917
        (  9, tvrx2_tda18272_rfcal_result_t() )
918
        ( 10, tvrx2_tda18272_rfcal_result_t() )
919
        ( 11, tvrx2_tda18272_rfcal_result_t() )
920
    ;
921

    
922
    _rfcal_coeffs = map_list_of
923
        ( 0, tvrx2_tda18272_rfcal_coeffs_t(0) )
924
        ( 1, tvrx2_tda18272_rfcal_coeffs_t(1) )
925
        ( 2, tvrx2_tda18272_rfcal_coeffs_t(3) )
926
        ( 3, tvrx2_tda18272_rfcal_coeffs_t(4) )
927
        ( 4, tvrx2_tda18272_rfcal_coeffs_t(6) )
928
        ( 5, tvrx2_tda18272_rfcal_coeffs_t(7) )
929
        ( 6, tvrx2_tda18272_rfcal_coeffs_t(9) )
930
        ( 7, tvrx2_tda18272_rfcal_coeffs_t(10) )
931
    ;
932

    
933
    //set the gpio directions and atr controls (identically)
934
    this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, 0); // All unused in atr
935
    this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, OUTPUT_MASK); // Set outputs
936

    
937
    double ref_clock=0.0;
938

    
939
    //configure ref_clock
940

    
941
    /*
942
    std::vector<double> clock_rates = this->get_iface()->get_clock_rates(dboard_iface::UNIT_RX);
943
    BOOST_FOREACH(ref_clock, uhd::sorted(clock_rates)){
944
        if (ref_clock < 16.0e6) continue; 
945
        if (ref_clock >= 16.0e6) break; 
946
    }
947
    this->get_iface()->set_clock_rate(dboard_iface::UNIT_RX, ref_clock);
948
    */
949

    
950
    ref_clock = this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX);
951

    
952
    if (ref_clock == 64.0e6) {
953
        this->get_iface()->set_gpio_out(dboard_iface::UNIT_RX, REFCLOCK_DIV4);
954

    
955
        UHD_LOGV(often) << boost::format(
956
            "TVRX2 (%s): Dividing Refclock by 4"
957
        ) % (get_subdev_name()) << std::endl;
958

    
959
        _freq_scalar = (4*16.0e6)/(this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX));
960
    } else if (ref_clock == 100e6) {
961
        this->get_iface()->set_gpio_out(dboard_iface::UNIT_RX, REFCLOCK_DIV6);
962

    
963
        UHD_LOGV(often) << boost::format(
964
            "TVRX2 (%s): Dividing Refclock by 6"
965
        ) % (get_subdev_name()) << std::endl;
966

    
967
        _freq_scalar = (6*16.0e6)/this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX);
968
    } else {
969
        this->get_iface()->set_gpio_out(dboard_iface::UNIT_RX, REFCLOCK_DIV6);
970
        UHD_MSG(warning) << boost::format("Unsupported ref_clock %0.2f, valid options 64e6 and 100e6") % ref_clock << std::endl;
971
        _freq_scalar = 1.0;
972
    }
973

    
974
    //enable only the clocks we need
975
    this->get_iface()->set_clock_enabled(dboard_iface::UNIT_RX, true);
976

    
977
    UHD_LOGV(often) << boost::format(
978
        "TVRX2 (%s): Refclock %f Hz, scalar = %f"
979
    ) % (get_subdev_name()) % (this->get_iface()->get_clock_rate(dboard_iface::UNIT_RX)) % _freq_scalar << std::endl;
980

    
981
    //set defaults for LO, gains, and filter bandwidth
982
    _bandwidth = 10e6;
983

    
984
    _if_freq = 12.5e6;
985

    
986
    _lo_freq = tvrx2_freq_range.start();
987

    
988
    _enabled = false;
989

    
990
    //send initial register settings
991
    //this->read_reg(0x0, 0x43);
992
    //this->send_reg(0x0, 0x43);
993

    
994
    //send magic xtal_cal_dac setting
995
    send_reg(0x65, 0x65);
996

    
997
    _tda18272hnm_regs.irq_polarity = tda18272hnm_regs_t::IRQ_POLARITY_RAISED_VCC;
998
    _tda18272hnm_regs.irq_clear = tda18272hnm_regs_t::IRQ_CLEAR_TRUE;
999
    send_reg(0x37, 0x37);
1000
    send_reg(0xA, 0xA);
1001

    
1002
    send_reg(0x31, 0x31); //N_CP_Current
1003
    send_reg(0x36, 0x36); //RSSI_Clock
1004
    send_reg(0x24, 0x25); //AGC1_Do_step
1005
    send_reg(0x2C, 0x2C); //AGC1_Do_step
1006
    send_reg(0x2E, 0x2E); //AGC2_Do_step
1007
    send_reg(0x0E, 0x0E); //AGCs_Up_step_assym
1008
    send_reg(0x11, 0x11); //AGCs_Do_step_assym
1009

    
1010
    //intialize i2c
1011
    //soft_calibration();
1012
    //tvrx2_tda18272_init_rfcal();
1013
    transition_0();
1014
}
1015

    
1016
void tvrx2::set_enabled(void){
1017
    //setup tuner parameters
1018
    transition_1();
1019

    
1020
    transition_2(int(tvrx2_freq_range.start()));
1021

    
1022
    test_rf_filter_robustness();
1023

    
1024
    BOOST_FOREACH(const std::string &name, tvrx2_gain_ranges.keys()){
1025
        set_gain(tvrx2_gain_ranges[name].start(), name);
1026
    }
1027

    
1028
    set_bandwidth(_bandwidth); // default bandwidth from datasheet
1029

    
1030
    //transition_2 equivalent
1031
    set_lo_freq(tvrx2_freq_range.start());
1032

    
1033
    //enter standby mode
1034
    transition_3();
1035
    _enabled = true;
1036
}
1037

    
1038
tvrx2::~tvrx2(void){
1039
    UHD_LOGV(often) << boost::format(
1040
        "TVRX2 (%s): Called Destructor"
1041
    ) % (get_subdev_name()) << std::endl;
1042
    if (_enabled) set_disabled();
1043
}
1044

    
1045
void tvrx2::set_disabled(void){
1046
    //enter standby mode
1047
    transition_3();
1048
    _enabled = false;
1049
}
1050

    
1051

    
1052
/***********************************************************************
1053
 * TDA18272 Register IO Functions
1054
 **********************************************************************/
1055
void tvrx2::set_scaled_rf_freq(double rf_freq){
1056
    _tda18272hnm_regs.set_rf_freq(_freq_scalar*rf_freq/1e3);
1057
}
1058

    
1059
double tvrx2::get_scaled_rf_freq(void){
1060
    return _tda18272hnm_regs.get_rf_freq()*1e3/_freq_scalar;
1061
}
1062

    
1063
void tvrx2::set_scaled_if_freq(double if_freq){
1064
    _tda18272hnm_regs.if_freq = int(_freq_scalar*if_freq/(50e3)); //max 12.8MHz??
1065
}
1066

    
1067
double tvrx2::get_scaled_if_freq(void){
1068
    return _tda18272hnm_regs.if_freq*50e3/_freq_scalar;
1069
}
1070

    
1071
void tvrx2::send_reg(boost::uint8_t start_reg, boost::uint8_t stop_reg){
1072
    start_reg = boost::uint8_t(uhd::clip(int(start_reg), 0x0, 0x43));
1073
    stop_reg = boost::uint8_t(uhd::clip(int(stop_reg), 0x0, 0x43));
1074

    
1075
    for(boost::uint8_t start_addr=start_reg; start_addr <= stop_reg; start_addr += sizeof(boost::uint32_t) - 1){
1076
        int num_bytes = int(stop_reg - start_addr + 1) > int(sizeof(boost::uint32_t)) - 1 ? sizeof(boost::uint32_t) - 1 : stop_reg - start_addr + 1;
1077

    
1078
        //create buffer for register data (+1 for start address)
1079
        byte_vector_t regs_vector(num_bytes + 1);
1080

    
1081
        //first byte is the address of first register
1082
        regs_vector[0] = start_addr;
1083

    
1084
        //get the register data
1085
        for(int i=0; i<num_bytes; i++){
1086
            regs_vector[1+i] = _tda18272hnm_regs.get_reg(start_addr+i);
1087
            UHD_LOGV(often) << boost::format(
1088
                "TVRX2 (%s, 0x%02x): send reg 0x%02x, value 0x%04x, start_addr = 0x%04x, num_bytes %d"
1089
            ) % (get_subdev_name()) % int(tvrx2_sd_name_to_i2c_addr[get_subdev_name()]) % int(start_addr+i) % int(regs_vector[1+i]) % int(start_addr) % num_bytes << std::endl;
1090
        }
1091

    
1092
        //send the data
1093
        this->get_iface()->write_i2c(
1094
            tvrx2_sd_name_to_i2c_addr[get_subdev_name()], regs_vector
1095
        );
1096
    }
1097
}
1098

    
1099
void tvrx2::read_reg(boost::uint8_t start_reg, boost::uint8_t stop_reg){
1100
    static const boost::uint8_t status_addr = 0x0;
1101
    start_reg = boost::uint8_t(uhd::clip(int(start_reg), 0x0, 0x43));
1102
    stop_reg = boost::uint8_t(uhd::clip(int(stop_reg), 0x0, 0x43));
1103

    
1104
    for(boost::uint8_t start_addr=start_reg; start_addr <= stop_reg; start_addr += sizeof(boost::uint32_t)){
1105
        int num_bytes = int(stop_reg - start_addr + 1) > int(sizeof(boost::uint32_t)) ? sizeof(boost::uint32_t) : stop_reg - start_addr + 1;
1106

    
1107
        //create buffer for starting address
1108
        byte_vector_t start_address_vector(1);
1109

    
1110
        //first byte is the address of first register
1111
        start_address_vector[0] = start_addr;
1112

    
1113
        //send the start address
1114
        this->get_iface()->write_i2c(
1115
            tvrx2_sd_name_to_i2c_addr[get_subdev_name()], start_address_vector
1116
        );
1117

    
1118
        //create buffer for register data
1119
        byte_vector_t regs_vector(num_bytes);
1120

    
1121
        //read from i2c
1122
        regs_vector = this->get_iface()->read_i2c(
1123
            tvrx2_sd_name_to_i2c_addr[get_subdev_name()], num_bytes
1124
        );
1125

    
1126
        for(boost::uint8_t i=0; i < num_bytes; i++){
1127
            if (i + start_addr >= status_addr){
1128
                _tda18272hnm_regs.set_reg(i + start_addr, regs_vector[i]);
1129
            }
1130
            UHD_LOGV(often) << boost::format(
1131
                "TVRX2 (%s, 0x%02x): read reg 0x%02x, value 0x%04x, start_addr = 0x%04x, num_bytes %d"
1132
            ) % (get_subdev_name()) % int(tvrx2_sd_name_to_i2c_addr[get_subdev_name()]) % int(start_addr+i) % int(regs_vector[i]) % int(start_addr) % num_bytes << std::endl;
1133
        }
1134
    }
1135
}
1136

    
1137

    
1138
/***********************************************************************
1139
 * TDA18272 Calibration Functions
1140
 **********************************************************************/
1141
freq_range_t tvrx2::get_tda18272_rfcal_result_freq_range(boost::uint32_t result)
1142
{
1143

    
1144
    uhd::dict<boost::uint32_t, freq_range_t> result_to_cal_freq_ranges_map = map_list_of
1145
        ( 0, freq_range_t(
1146
                 (double) tvrx2_tda18272_cal_map[0].cal_freq[_tda18272hnm_regs.rfcal_freq0] * _freq_scalar,
1147
                 (double) tvrx2_tda18272_cal_map[1].cal_freq[_tda18272hnm_regs.rfcal_freq1] * _freq_scalar
1148
                 ) )
1149
        ( 1, freq_range_t(
1150
                 (double) tvrx2_tda18272_cal_map[1].cal_freq[_tda18272hnm_regs.rfcal_freq1] * _freq_scalar,
1151
                 (double) tvrx2_tda18272_cal_map[2].cal_freq[_tda18272hnm_regs.rfcal_freq2] * _freq_scalar
1152
                 ) )
1153
        ( 2, freq_range_t(
1154
                 (double) tvrx2_tda18272_cal_map[2].cal_freq[_tda18272hnm_regs.rfcal_freq2] * _freq_scalar,
1155
                 (double) tvrx2_tda18272_cal_map[3].cal_freq[_tda18272hnm_regs.rfcal_freq3] * _freq_scalar
1156
                 ) )
1157
        ( 3, freq_range_t(
1158
                 (double) tvrx2_tda18272_cal_map[3].cal_freq[_tda18272hnm_regs.rfcal_freq3] * _freq_scalar,
1159
                 (double) tvrx2_tda18272_cal_map[4].cal_freq[_tda18272hnm_regs.rfcal_freq4] * _freq_scalar
1160
                 ) )
1161
        ( 4, freq_range_t(
1162
                 (double) tvrx2_tda18272_cal_map[4].cal_freq[_tda18272hnm_regs.rfcal_freq4] * _freq_scalar,
1163
                 (double) tvrx2_tda18272_cal_map[5].cal_freq[_tda18272hnm_regs.rfcal_freq5] * _freq_scalar
1164
                 ) )
1165
        ( 5, freq_range_t(
1166
                 (double) tvrx2_tda18272_cal_map[5].cal_freq[_tda18272hnm_regs.rfcal_freq5] * _freq_scalar,
1167
                 (double) tvrx2_tda18272_cal_map[6].cal_freq[_tda18272hnm_regs.rfcal_freq6] * _freq_scalar
1168
                 ) )
1169
        ( 6, freq_range_t(
1170
                 (double) tvrx2_tda18272_cal_map[6].cal_freq[_tda18272hnm_regs.rfcal_freq6] * _freq_scalar,
1171
                 (double) tvrx2_tda18272_cal_map[7].cal_freq[_tda18272hnm_regs.rfcal_freq7] * _freq_scalar
1172
                 ) )
1173
        ( 7, freq_range_t(
1174
                 (double) tvrx2_tda18272_cal_map[7].cal_freq[_tda18272hnm_regs.rfcal_freq7] * _freq_scalar,
1175
                 (double) tvrx2_tda18272_cal_map[8].cal_freq[_tda18272hnm_regs.rfcal_freq8] * _freq_scalar
1176
                 ) )
1177
        ( 8, freq_range_t(
1178
                 (double) tvrx2_tda18272_cal_map[8].cal_freq[_tda18272hnm_regs.rfcal_freq8] * _freq_scalar,
1179
                 (double) tvrx2_tda18272_cal_map[9].cal_freq[_tda18272hnm_regs.rfcal_freq9] * _freq_scalar
1180
                 ) )
1181
        ( 9, freq_range_t(
1182
                 (double) tvrx2_tda18272_cal_map[9].cal_freq[_tda18272hnm_regs.rfcal_freq9] * _freq_scalar,
1183
                 (double) tvrx2_tda18272_cal_map[10].cal_freq[_tda18272hnm_regs.rfcal_freq10] * _freq_scalar
1184
                 ) )
1185
        (10, freq_range_t(
1186
                 (double) tvrx2_tda18272_cal_map[10].cal_freq[_tda18272hnm_regs.rfcal_freq10] * _freq_scalar,
1187
                 (double) tvrx2_tda18272_cal_map[11].cal_freq[_tda18272hnm_regs.rfcal_freq11] * _freq_scalar
1188
                 ) )
1189
    ;
1190

    
1191
    if (result < 11)
1192
        return result_to_cal_freq_ranges_map[result]; 
1193
    else
1194
        return freq_range_t(0.0, 0.0);
1195
}
1196

    
1197

    
1198
/*
1199
 * Initialize the RF Filter calibration maps after hardware init
1200
 */
1201
void tvrx2::tvrx2_tda18272_init_rfcal(void)
1202
{
1203

    
1204
    /* read byte 0x38-0x43 */
1205
    read_reg(0x38, 0x43);
1206

    
1207
    uhd::dict<boost::uint32_t, boost::uint8_t> result_to_cal_regs = map_list_of
1208
        ( 0, _tda18272hnm_regs.rfcal_log_1)
1209
        ( 1, _tda18272hnm_regs.rfcal_log_2)
1210
        ( 2, _tda18272hnm_regs.rfcal_log_3)
1211
        ( 3, _tda18272hnm_regs.rfcal_log_4)
1212
        ( 4, _tda18272hnm_regs.rfcal_log_5)
1213
        ( 5, _tda18272hnm_regs.rfcal_log_6)
1214
        ( 6, _tda18272hnm_regs.rfcal_log_7)
1215
        ( 7, _tda18272hnm_regs.rfcal_log_8)
1216
        ( 8, _tda18272hnm_regs.rfcal_log_9)
1217
        ( 9, _tda18272hnm_regs.rfcal_log_10)
1218
        (10, _tda18272hnm_regs.rfcal_log_11)
1219
        (11, _tda18272hnm_regs.rfcal_log_12)
1220
    ;
1221

    
1222

    
1223
    // Loop through rfcal_log_* registers, initialize _rfcal_results
1224
    BOOST_FOREACH(const boost::uint32_t &result, result_to_cal_regs.keys())
1225
        _rfcal_results[result].delta_c = result_to_cal_regs[result] > 63 ? result_to_cal_regs[result] - 128 : result_to_cal_regs[result];
1226

    
1227
    /* read byte 0x26-0x2B */
1228
    read_reg(0x26, 0x2B);
1229

    
1230
    // Loop through rfcal_byte_* registers, initialize _rfcal_coeffs
1231
    BOOST_FOREACH(const boost::uint32_t &subband, _rfcal_coeffs.keys())
1232
    {
1233
        freq_range_t subband_freqs;
1234

    
1235
        boost::uint32_t result = _rfcal_coeffs[subband].cal_number;
1236

    
1237
        subband_freqs = get_tda18272_rfcal_result_freq_range(result);
1238

    
1239
        _rfcal_coeffs[subband].RF_B1 = _rfcal_results[result].delta_c + tvrx2_tda18272_cal_map[result].c_offset[_rfcal_results[result].c_offset];
1240

    
1241
        boost::uint32_t quotient = (((_rfcal_results[result+1].delta_c + tvrx2_tda18272_cal_map[result+1].c_offset[_rfcal_results[result].c_offset])
1242
                                        - (_rfcal_results[result].delta_c + tvrx2_tda18272_cal_map[result].c_offset[_rfcal_results[result].c_offset])) * 1000000);
1243

    
1244
        boost::uint32_t divisor = ((boost::int32_t)(subband_freqs.stop() - subband_freqs.start())/1000);
1245

    
1246
        _rfcal_coeffs[subband].RF_A1 = quotient / divisor;
1247

    
1248
    }
1249

    
1250
}
1251

    
1252
/*
1253
 * Apply calibration coefficients to RF Filter tuning
1254
 */
1255
void tvrx2::tvrx2_tda18272_tune_rf_filter(boost::uint32_t uRF)
1256
{
1257
    boost::uint32_t                  uCounter = 0;
1258
    boost::uint8_t                   cal_result = 0;
1259
    boost::uint32_t                  uRFCal0 = 0;
1260
    boost::uint32_t                  uRFCal1 = 0;
1261
    boost::uint8_t                   subband = 0;
1262
    boost::int32_t                   cProg = 0;
1263
    boost::uint8_t                   gain_taper = 0;
1264
    boost::uint8_t                   RFBand = 0;
1265
    boost::int32_t                   RF_A1 = 0;
1266
    boost::int32_t                   RF_B1 = 0;
1267
    freq_range_t                     subband_freqs;
1268

    
1269
    /* read byte 0x26-0x2B */
1270
    read_reg(0x26, 0x2B);
1271

    
1272
    subband_freqs = get_tda18272_rfcal_result_freq_range(1);
1273
    uRFCal0 = subband_freqs.start();
1274
    subband_freqs = get_tda18272_rfcal_result_freq_range(4);
1275
    uRFCal1 = subband_freqs.start();
1276

    
1277
    if(uRF < uRFCal0)
1278
        subband = 0;
1279
    else if(uRF < 145700000)
1280
        subband = 1;
1281
    else if(uRF < uRFCal1)
1282
        subband = 2;
1283
    else if(uRF < 367400000)
1284
        subband = 3;
1285
    else
1286
    {
1287
        subband_freqs = get_tda18272_rfcal_result_freq_range(7);
1288
        uRFCal0 = subband_freqs.start();
1289
        subband_freqs = get_tda18272_rfcal_result_freq_range(10);
1290
        uRFCal1 = subband_freqs.start();
1291

    
1292
        if(uRF < uRFCal0)
1293
            subband = 4;
1294
        else if(uRF < 625000000)
1295
            subband = 5;
1296
        else if(uRF < uRFCal1)
1297
            subband = 6;
1298
        else
1299
            subband = 7;
1300
    }
1301

    
1302
    cal_result = _rfcal_coeffs[subband].cal_number;
1303
    subband_freqs = get_tda18272_rfcal_result_freq_range(cal_result);
1304
    uRFCal0 = subband_freqs.start();
1305

    
1306
    RF_A1 = _rfcal_coeffs[subband].RF_A1;
1307
    RF_B1 = _rfcal_coeffs[subband].RF_B1;
1308

    
1309
    uCounter = 0;
1310
    do uCounter ++;
1311
    while (uRF >= tvrx2_tda18272_freq_map[uCounter].rf_max && uCounter < TVRX2_TDA18272_FREQ_MAP_ENTRIES);
1312

    
1313
    cProg = tvrx2_tda18272_freq_map[uCounter - 1].c_prog;
1314
    gain_taper = tvrx2_tda18272_freq_map[uCounter - 1].gain_taper;
1315
    RFBand = tvrx2_tda18272_freq_map[uCounter - 1].rf_band;
1316

    
1317
    cProg = (boost::int32_t)(cProg + RF_B1 + (RF_A1*((boost::int32_t)(uRF - uRFCal0)/1000))/1000000);
1318

    
1319
    if(cProg>255)   cProg = 255;
1320
    if(cProg<0)     cProg = 0;
1321

    
1322
    _tda18272hnm_regs.rf_filter_bypass = 1;
1323
    _tda18272hnm_regs.rf_filter_cap = (boost::uint8_t) cProg;
1324
    _tda18272hnm_regs.gain_taper = gain_taper;
1325
    _tda18272hnm_regs.rf_filter_band = RFBand;
1326

    
1327
    UHD_LOGV(often) << boost::format(
1328
        "\nTVRX2 (%s): Software Calibration:\n"
1329
        "\tRF Filter Bypass = %d\n"
1330
        "\tRF Filter Cap    = %d\n"
1331
        "\tRF Filter Band   = %d\n"
1332
        "\tGain Taper       = %d\n") 
1333
        % (get_subdev_name())
1334
        % int(_tda18272hnm_regs.rf_filter_bypass)
1335
        % int(_tda18272hnm_regs.rf_filter_cap)
1336
        % int(_tda18272hnm_regs.rf_filter_band) 
1337
        % int(_tda18272hnm_regs.gain_taper)
1338
        << std::endl;
1339

    
1340
    send_reg(0x2c, 0x2f);
1341
}
1342

    
1343
void tvrx2::soft_calibration(void){
1344
    UHD_LOGV(often) << boost::format(
1345
        "\nTVRX2 (%s): Software Calibration: Initialize Tuner, Calibrate and Standby\n") % (get_subdev_name()) << std::endl;
1346

    
1347
    _tda18272hnm_regs.sm = tda18272hnm_regs_t::SM_NORMAL;
1348
    _tda18272hnm_regs.sm_lna = tda18272hnm_regs_t::SM_LNA_ON;
1349
    _tda18272hnm_regs.sm_pll = tda18272hnm_regs_t::SM_PLL_ON;
1350

    
1351
    send_reg(0x6, 0x6);
1352
    read_reg(0x6, 0x6);
1353

    
1354
    read_reg(0x19, 0x1A);
1355
    read_reg(0x26, 0x2B);
1356

    
1357
    _tda18272hnm_regs.rfcal_freq0  = 0x2;
1358
    _tda18272hnm_regs.rfcal_freq1  = 0x2;
1359
    _tda18272hnm_regs.rfcal_freq2  = 0x2;
1360
    _tda18272hnm_regs.rfcal_freq3  = 0x2;
1361
    _tda18272hnm_regs.rfcal_freq4  = 0x2;
1362
    _tda18272hnm_regs.rfcal_freq5  = 0x2;
1363
    _tda18272hnm_regs.rfcal_freq6  = 0x2;
1364
    _tda18272hnm_regs.rfcal_freq7  = 0x2;
1365
    _tda18272hnm_regs.rfcal_freq8  = 0x2;
1366
    _tda18272hnm_regs.rfcal_freq9  = 0x2;
1367
    _tda18272hnm_regs.rfcal_freq10 = 0x2;
1368
    _tda18272hnm_regs.rfcal_freq11 = 0x2;
1369

    
1370
    send_reg(0x26, 0x2B);
1371

    
1372
    _tda18272hnm_regs.set_reg(0x19, 0x3B); //set MSM_byte_1 for calibration per datasheet
1373
    _tda18272hnm_regs.set_reg(0x1A, 0x01); //set MSM_byte_2 for launching calibration
1374

    
1375
    send_reg(0x19, 0x1A);
1376

    
1377
    wait_irq();
1378

    
1379
    send_reg(0x1D, 0x1D); //Fmax_LO
1380
    send_reg(0x0C, 0x0C); //LT_Enable
1381
    send_reg(0x1B, 0x1B); //PSM_AGC1
1382
    send_reg(0x0C, 0x0C); //AGC1_6_15dB
1383

    
1384
    //set spread spectrum for clock 
1385
    //FIXME: NXP turns clock spread on and off 
1386
    //   based on where clock spurs would be relative to RF frequency
1387
    //   we should do this also
1388
    _tda18272hnm_regs.digital_clock = tda18272hnm_regs_t::DIGITAL_CLOCK_SPREAD_OFF;
1389
    if (get_subdev_name() == "RX1")
1390
        //_tda18272hnm_regs.xtout = tda18272hnm_regs_t::XTOUT_NO;
1391
        _tda18272hnm_regs.xtout = tda18272hnm_regs_t::XTOUT_16MHZ;
1392
    else
1393
        //_tda18272hnm_regs.xtout = tda18272hnm_regs_t::XTOUT_NO;
1394
        _tda18272hnm_regs.xtout = tda18272hnm_regs_t::XTOUT_16MHZ;
1395
    
1396
    send_reg(0x14, 0x14);
1397

    
1398
    _tda18272hnm_regs.set_reg(0x36, 0x0E); //sets clock mode
1399
    send_reg(0x36, 0x36);
1400

    
1401
    //go to standby mode
1402
    _tda18272hnm_regs.sm = tda18272hnm_regs_t::SM_STANDBY;
1403
    send_reg(0x6, 0x6);
1404
}
1405

    
1406
void tvrx2::test_rf_filter_robustness(void){
1407
    typedef uhd::dict<std::string, std::string> tvrx2_filter_ratings_t;
1408
    typedef uhd::dict<std::string, double> tvrx2_filter_margins_t;
1409

    
1410
    tvrx2_filter_margins_t _filter_margins;
1411
    tvrx2_filter_ratings_t _filter_ratings;
1412

    
1413
    read_reg(0x38, 0x43);
1414

    
1415
    uhd::dict<std::string, boost::uint8_t> filter_cal_regs = map_list_of
1416
        ("VHFLow_0", 0x38)
1417
        ("VHFLow_1", 0x3a)
1418
        ("VHFHigh_0", 0x3b)
1419
        ("VHFHigh_1", 0x3d)
1420
        ("UHFLow_0", 0x3e)
1421
        ("UHFLow_1", 0x40)
1422
        ("UHFHigh_0", 0x41)
1423
        ("UHFHigh_1", 0x43)
1424
    ;
1425

    
1426
    BOOST_FOREACH(const std::string &name, filter_cal_regs.keys()){
1427
        boost::uint8_t cal_result = _tda18272hnm_regs.get_reg(filter_cal_regs[name]);
1428
        if (cal_result & 0x80) {
1429
            _filter_ratings.set(name, "E");
1430
            _filter_margins.set(name, 0.0);
1431
        }
1432
        else {
1433
            double partial;
1434

    
1435
            if (name == "VHFLow_0")
1436
                partial = 100 * (45 - 39.8225 * (1 + (0.31 * (cal_result < 64 ? cal_result : cal_result - 128)) / 1.0 / 100.0)) / 45.0;
1437

    
1438
            else if (name == "VHFLow_1")
1439
                partial = 100 * (152.1828 * (1 + (1.53 * (cal_result < 64 ? cal_result : cal_result - 128)) / 1.0 / 100.0) - (144.896 - 6)) / (144.896 - 6); 
1440

    
1441
            else if (name == "VHFHigh_0")
1442
                partial = 100 * ((144.896 + 6) - 135.4063 * (1 + (0.27 * (cal_result < 64 ? cal_result : cal_result - 128)) / 1.0 / 100.0)) / (144.896 + 6);
1443

    
1444
            else if (name == "VHFHigh_1")
1445
                partial = 100 * (383.1455 * (1 + (0.91 * (cal_result < 64 ? cal_result : cal_result - 128)) / 1.0 / 100.0) - (367.104 - 8)) / (367.104 - 8);
1446

    
1447
            else if (name == "UHFLow_0")
1448
                partial = 100 * ((367.104 + 8) - 342.6224 * (1 + (0.21 * (cal_result < 64 ? cal_result : cal_result - 128)) / 1.0 / 100.0)) / (367.104 + 8);
1449

    
1450
            else if (name == "UHFLow_1")
1451
                partial = 100 * (662.5595 * (1 + (0.33 * (cal_result < 64 ? cal_result : cal_result - 128)) / 1.0 / 100.0) - (624.128 - 2)) / (624.128 - 2);
1452

    
1453
            else if (name == "UHFHigh_0")
1454
                partial = 100 * ((624.128 + 2) - 508.2747 * (1 + (0.23 * (cal_result < 64 ? cal_result : cal_result - 128)) / 1.0 / 100.0)) / (624.128 + 2);
1455

    
1456
            else if (name == "UHFHigh_1")
1457
                partial = 100 * (947.8913 * (1 + (0.3 * (cal_result < 64 ? cal_result : cal_result - 128)) / 1.0 / 100.0) - (866 - 14)) / (866 - 14);
1458

    
1459
            else
1460
                UHD_THROW_INVALID_CODE_PATH();
1461

    
1462
            _filter_margins.set(name, 0.0024 * partial * partial * partial - 0.101 * partial * partial + 1.629 * partial + 1.8266);
1463
            _filter_ratings.set(name, _filter_margins[name] >= 0.0 ? "H" : "L");
1464
        }
1465
    }
1466

    
1467
    std::stringstream robustness_message;
1468
    robustness_message << boost::format("TVRX2 (%s): RF Filter Robustness Results:") % (get_subdev_name()) << std::endl;
1469
    BOOST_FOREACH(const std::string &name, uhd::sorted(_filter_ratings.keys())){
1470
        robustness_message << boost::format("\t%s:\tMargin = %0.2f,\tRobustness = %c") % name % (_filter_margins[name]) % (_filter_ratings[name]) << std::endl;
1471
    }
1472

    
1473
    UHD_LOGV(often) << robustness_message.str();
1474
}
1475

    
1476
/***********************************************************************
1477
 * TDA18272 State Functions
1478
 **********************************************************************/
1479
void tvrx2::transition_0(void){
1480
    //Transition 0: Initialize Tuner and place in standby
1481
    UHD_LOGV(often) << boost::format(
1482
        "\nTVRX2 (%s): Transistion 0: Initialize Tuner, Calibrate and Standby\n") % (get_subdev_name()) << std::endl;
1483

    
1484
    //Check for Power-On Reset, if reset, initialze tuner
1485
    if (get_power_reset()) {
1486
        _tda18272hnm_regs.sm = tda18272hnm_regs_t::SM_NORMAL;
1487
        _tda18272hnm_regs.sm_lna = tda18272hnm_regs_t::SM_LNA_ON;
1488
        _tda18272hnm_regs.sm_pll = tda18272hnm_regs_t::SM_PLL_ON;
1489

    
1490
        send_reg(0x6, 0x6);
1491
        read_reg(0x6, 0x6);
1492

    
1493
        read_reg(0x19, 0x1A);
1494

    
1495
        _tda18272hnm_regs.set_reg(0x19, 0x3B); //set MSM_byte_1 for calibration per datasheet
1496
        _tda18272hnm_regs.set_reg(0x1A, 0x01); //set MSM_byte_2 for launching calibration
1497

    
1498
        send_reg(0x19, 0x1A);
1499

    
1500
        wait_irq();
1501
    }
1502

    
1503
    //send magic xtal_cal_dac setting
1504
    send_reg(0x65, 0x65);
1505

    
1506
    send_reg(0x1D, 0x1D); //Fmax_LO
1507
    send_reg(0x0C, 0x0C); //LT_Enable
1508
    send_reg(0x1B, 0x1B); //PSM_AGC1
1509
    send_reg(0x0C, 0x0C); //AGC1_6_15dB
1510

    
1511
    //set spread spectrum for clock 
1512
    //FIXME: NXP turns clock spread on and off 
1513
    //   based on where clock spurs would be relative to RF frequency
1514
    //   we should do this also
1515
    _tda18272hnm_regs.digital_clock = tda18272hnm_regs_t::DIGITAL_CLOCK_SPREAD_OFF;
1516
    if (get_subdev_name() == "RX1")
1517
        //_tda18272hnm_regs.xtout = tda18272hnm_regs_t::XTOUT_NO;
1518
        _tda18272hnm_regs.xtout = tda18272hnm_regs_t::XTOUT_16MHZ;
1519
    else
1520
        //_tda18272hnm_regs.xtout = tda18272hnm_regs_t::XTOUT_NO;
1521
        _tda18272hnm_regs.xtout = tda18272hnm_regs_t::XTOUT_16MHZ;
1522
    
1523
    send_reg(0x14, 0x14);
1524

    
1525
    _tda18272hnm_regs.set_reg(0x36, 0x0E); //sets clock mode
1526
    send_reg(0x36, 0x36);
1527

    
1528
    //go to standby mode
1529
    _tda18272hnm_regs.sm = tda18272hnm_regs_t::SM_STANDBY;
1530
    send_reg(0x6, 0x6);
1531
}
1532

    
1533
void tvrx2::transition_1(void){
1534
    //Transition 1: Select TV Standard
1535
    UHD_LOGV(often) << boost::format(
1536
        "\nTVRX2 (%s): Transistion 1: Select TV Standard\n") % (get_subdev_name()) << std::endl;
1537

    
1538
    //send magic xtal_cal_dac setting
1539
    send_reg(0x65, 0x65);
1540

    
1541
    //Choose IF Byte 1 Setting
1542
    //_tda18272hnm_regs.if_hp_fc = tda18272hnm_regs_t::IF_HP_FC_0_4MHZ;
1543
    //_tda18272hnm_regs.if_notch = tda18272hnm_regs_t::IF_NOTCH_OFF;
1544
    //_tda18272hnm_regs.lp_fc_offset = tda18272hnm_regs_t::LP_FC_OFFSET_0_PERCENT;
1545
    //_tda18272hnm_regs.lp_fc = tda18272hnm_regs_t::LP_FC_10_0MHZ;
1546
    //send_reg(0x13, 0x13);
1547

    
1548
    //Choose IR Mixer Byte 2 Setting
1549
    //_tda18272hnm_regs.hi_pass = tda18272hnm_regs_t::HI_PASS_DISABLE;
1550
    //_tda18272hnm_regs.dc_notch = tda18272hnm_regs_t::DC_NOTCH_OFF;
1551
    send_reg(0x23, 0x23);
1552

    
1553
    //Set AGC TOP Bytes
1554
    send_reg(0x0C, 0x13);
1555

    
1556
    //Set PSM Byt1
1557
    send_reg(0x1B, 0x1B);
1558

    
1559
    //Choose IF Frequency, setting is 50KHz steps
1560
    set_scaled_if_freq(_if_freq);
1561
    send_reg(0x15, 0x15);
1562
}
1563

    
1564
void tvrx2::transition_2(int rf_freq){
1565
    //Transition 2: Select RF Frequency after changing TV Standard
1566
    UHD_LOGV(often) << boost::format(
1567
        "\nTVRX2 (%s): Transistion 2: Select RF Frequency after changing TV Standard\n") % (get_subdev_name()) << std::endl;
1568

    
1569
    //send magic xtal_cal_dac setting
1570
    send_reg(0x65, 0x65);
1571

    
1572
    //Wake up from Standby
1573
    _tda18272hnm_regs.sm = tda18272hnm_regs_t::SM_NORMAL;
1574
    _tda18272hnm_regs.sm_lna = tda18272hnm_regs_t::SM_LNA_ON;
1575
    _tda18272hnm_regs.sm_pll = tda18272hnm_regs_t::SM_PLL_ON;
1576
    
1577
    send_reg(0x6, 0x6);
1578
    
1579
    //Set Clock Mode
1580
    _tda18272hnm_regs.set_reg(0x36, 0x00);
1581
    send_reg(0x36, 0x36);
1582
    
1583
    //Set desired RF Frequency
1584
    set_scaled_rf_freq(rf_freq);
1585
    send_reg(0x16, 0x18);
1586
    
1587
    //Lock PLL and tune RF Filters
1588
    _tda18272hnm_regs.set_reg(0x19, 0x41); //set MSM_byte_1 for RF Filters Tuning, PLL Locking
1589
    _tda18272hnm_regs.set_reg(0x1A, 0x01); //set MSM_byte_2 for launching calibration
1590
    
1591
    send_reg(0x19, 0x1A);
1592
    
1593
    wait_irq();
1594

    
1595
    tvrx2_tda18272_tune_rf_filter(rf_freq);
1596

    
1597
    ////LO Lock state in Reg 0x5 LSB
1598
    //read_reg(0x6, 0x6);
1599

    
1600
}
1601

    
1602
void tvrx2::transition_3(void){
1603
    //Transition 3: Standby Mode
1604
    UHD_LOGV(often) << boost::format(
1605
        "\nTVRX2 (%s): Transistion 3: Standby Mode\n") % (get_subdev_name()) << std::endl;
1606

    
1607
    //send magic xtal_cal_dac setting
1608
    send_reg(0x65, 0x65);
1609

    
1610
    //Set clock mode
1611
    _tda18272hnm_regs.set_reg(0x36, 0x0E);
1612
    send_reg(0x36, 0x36);
1613

    
1614
    //go to standby mode
1615
    _tda18272hnm_regs.sm = tda18272hnm_regs_t::SM_STANDBY;
1616
    _tda18272hnm_regs.sm_lna = tda18272hnm_regs_t::SM_LNA_OFF;
1617
    _tda18272hnm_regs.sm_pll = tda18272hnm_regs_t::SM_PLL_OFF;
1618
    send_reg(0x6, 0x6);
1619
}
1620

    
1621
void tvrx2::transition_4(int rf_freq){
1622
    //Transition 4: Change RF Frequency without changing TV Standard
1623
    UHD_LOGV(often) << boost::format(
1624
        "\nTVRX2 (%s): Transistion 4: Change RF Frequency without changing TV Standard\n") % (get_subdev_name()) << std::endl;
1625

    
1626
    //send magic xtal_cal_dac setting
1627
    send_reg(0x65, 0x65);
1628

    
1629
    //Set desired RF Frequency
1630
    set_scaled_rf_freq(rf_freq);
1631
    send_reg(0x16, 0x18);
1632
    
1633
    //Lock PLL and tune RF Filters
1634
    _tda18272hnm_regs.set_reg(0x19, 0x41); //set MSM_byte_1 for RF Filters Tuning, PLL Locking
1635
    _tda18272hnm_regs.set_reg(0x1A, 0x01); //set MSM_byte_2 for launching calibration
1636
    
1637
    send_reg(0x19, 0x1A);
1638
    
1639
    wait_irq();
1640

    
1641
    tvrx2_tda18272_tune_rf_filter(rf_freq);
1642

    
1643
    ////LO Lock state in Reg 0x5 LSB
1644
    //read_reg(0x5, 0x6);
1645

    
1646
}
1647

    
1648
void tvrx2::wait_irq(void){
1649
    int timeout = 20; //irq waiting timeout in milliseconds
1650
    //int irq = (this->get_iface()->read_gpio(dboard_iface::UNIT_RX) & int(tvrx2_sd_name_to_irq_io[get_subdev_name()]));
1651
    bool irq = get_irq();
1652
    UHD_LOGV(often) << boost::format(
1653
        "\nTVRX2 (%s): Waiting on IRQ, subdev = %d, mask = 0x%x, Status: 0x%x\n") % (get_subdev_name()) % get_subdev_name() % (int(tvrx2_sd_name_to_irq_io[get_subdev_name()])) % irq << std::endl;
1654

    
1655
    while (not irq and timeout > 0) {
1656
        //irq = (this->get_iface()->read_gpio(dboard_iface::UNIT_RX) & tvrx2_sd_name_to_irq_io[get_subdev_name()]);
1657
        irq = get_irq();
1658
        boost::this_thread::sleep(boost::posix_time::milliseconds(10));
1659
        timeout -= 1;
1660
    }
1661

    
1662
    UHD_LOGV(often) << boost::format(
1663
        "\nTVRX2 (%s): IRQ Raised, subdev = %d, mask = 0x%x, Status: 0x%x, Timeout: %d\n") % (get_subdev_name()) % get_subdev_name() % (int(tvrx2_sd_name_to_irq_io[get_subdev_name()])) % irq % timeout << std::endl;
1664

    
1665
    read_reg(0xA, 0xB);
1666
    //UHD_ASSERT_THROW(timeout > 0);
1667
    if(timeout <= 0) UHD_MSG(warning) << boost::format(
1668
        "\nTVRX2 (%s): Timeout waiting on IRQ\n") % (get_subdev_name()) << std::endl;
1669

    
1670
    _tda18272hnm_regs.irq_clear = tda18272hnm_regs_t::IRQ_CLEAR_TRUE;
1671
    send_reg(0xA, 0xA);
1672
    read_reg(0xA, 0xB);
1673

    
1674
    irq = (this->get_iface()->read_gpio(dboard_iface::UNIT_RX) & tvrx2_sd_name_to_irq_io[get_subdev_name()]);
1675

    
1676
    UHD_LOGV(often) << boost::format(
1677
        "\nTVRX2 (%s): Cleared IRQ, subdev = %d, mask = 0x%x, Status: 0x%x\n") % (get_subdev_name()) % get_subdev_name() % (int(tvrx2_sd_name_to_irq_io[get_subdev_name()])) % irq << std::endl;
1678
}
1679

    
1680

    
1681

    
1682
/***********************************************************************
1683
 * Tuning
1684
 **********************************************************************/
1685
void tvrx2::set_lo_freq(double target_freq){
1686
    //target_freq = std::clip(target_freq, tvrx2_freq_range.min, tvrx2_freq_range.max);
1687

    
1688
    read_reg(0x6, 0x6);
1689

    
1690
    if (_tda18272hnm_regs.sm == tda18272hnm_regs_t::SM_STANDBY) {
1691
        transition_2(int(target_freq + _bandwidth/2 - get_scaled_if_freq()));
1692
    } else {
1693
        transition_4(int(target_freq + _bandwidth/2 - get_scaled_if_freq()));
1694
    }
1695
    read_reg(0x16, 0x18);
1696

    
1697
    //compute actual tuned frequency
1698
    _lo_freq = get_scaled_rf_freq() + get_scaled_if_freq(); // - _bandwidth/2;
1699

    
1700
    //debug output of calculated variables
1701
    UHD_LOGV(often) << boost::format(
1702
        "\nTVRX2 (%s): LO Frequency\n"
1703
        "\tRequested: \t%f\n"
1704
        "\tComputed: \t%f\n"
1705
        "\tReadback: \t%f\n"
1706
        "\tIF Frequency: \t%f\n") % (get_subdev_name()) % target_freq % double(int(target_freq/1e3)*1e3) % get_scaled_rf_freq() % get_scaled_if_freq() << std::endl;
1707

    
1708
    get_locked();
1709

    
1710
    test_rf_filter_robustness();
1711

    
1712
    UHD_LOGV(often) << boost::format(
1713
        "\nTVRX2 (%s): RSSI = %f dBm\n"
1714
    ) % (get_subdev_name()) % (get_rssi()) << std::endl;
1715
}
1716

    
1717
/***********************************************************************
1718
 * Gain Handling
1719
 **********************************************************************/
1720
/*
1721
 * Convert the requested gain into a dac voltage
1722
 */
1723
static double gain_to_if_gain_dac(double &gain){
1724
    //clip the input
1725
    gain = tvrx2_gain_ranges["IF"].clip(gain);
1726

    
1727
    //voltage level constants
1728
    static const double max_volts = double(1.7), min_volts = double(0.5);
1729
    static const double slope = (max_volts-min_volts)/tvrx2_gain_ranges["IF"].stop();
1730

    
1731
    //calculate the voltage for the aux dac
1732
    double dac_volts = gain*slope + min_volts;
1733

    
1734
    UHD_LOGV(often) << boost::format(
1735
        "TVRX2 IF Gain: %f dB, dac_volts: %f V"
1736
    ) % gain % dac_volts << std::endl;
1737

    
1738
    //the actual gain setting
1739
    gain = (dac_volts - min_volts)/slope;
1740

    
1741
    return dac_volts;
1742
}
1743

    
1744
void tvrx2::set_gain(double gain, const std::string &name){
1745
    assert_has(tvrx2_gain_ranges.keys(), name, "tvrx2 gain name");
1746

    
1747
    if (name == "IF"){
1748
        //write voltage to aux_dac
1749
        this->get_iface()->write_aux_dac(dboard_iface::UNIT_RX, tvrx2_sd_name_to_dac[get_subdev_name()], gain_to_if_gain_dac(gain));
1750
    }
1751
    else UHD_THROW_INVALID_CODE_PATH();
1752

    
1753
    //shadow gain setting
1754
    _gains[name] = gain;
1755
}
1756

    
1757
/***********************************************************************
1758
 * Bandwidth Handling
1759
 **********************************************************************/
1760
static tda18272hnm_regs_t::lp_fc_t bandwidth_to_lp_fc_reg(double &bandwidth){
1761
    int reg = uhd::clip(boost::math::iround((bandwidth-5.0e6)/1.0e6), 0, 4);
1762

    
1763
    switch(reg){
1764
    case 0:
1765
        bandwidth = 1.7e6;
1766
        return tda18272hnm_regs_t::LP_FC_1_7MHZ;
1767
    case 1:
1768
        bandwidth = 6e6;
1769
        return tda18272hnm_regs_t::LP_FC_6_0MHZ;
1770
    case 2:
1771
        bandwidth = 7e6;
1772
        return tda18272hnm_regs_t::LP_FC_7_0MHZ;
1773
    case 3:
1774
        bandwidth = 8e6;
1775
        return tda18272hnm_regs_t::LP_FC_8_0MHZ;
1776
    case 4:
1777
        bandwidth = 10e6;
1778
        return tda18272hnm_regs_t::LP_FC_10_0MHZ;
1779
    }
1780
    UHD_THROW_INVALID_CODE_PATH();
1781
}
1782

    
1783
void tvrx2::set_bandwidth(double bandwidth){
1784
    //compute low pass cutoff frequency setting
1785
    _tda18272hnm_regs.lp_fc = bandwidth_to_lp_fc_reg(bandwidth);
1786

    
1787
    //shadow bandwidth setting
1788
    _bandwidth = bandwidth;
1789

    
1790
    //update register
1791
    send_reg(0x13, 0x13);
1792

    
1793
    UHD_LOGV(often) << boost::format(
1794
        "TVRX2 (%s) Bandwidth (lp_fc): %f Hz, reg: %d"
1795
    ) % (get_subdev_name()) % _bandwidth % (int(_tda18272hnm_regs.lp_fc)) << std::endl;
1796
}
1797

    
1798
/***********************************************************************
1799
 * RX Get and Set
1800
 **********************************************************************/
1801
void tvrx2::rx_get(const wax::obj &key_, wax::obj &val){
1802
    named_prop_t key = named_prop_t::extract(key_);
1803

    
1804
    //handle the get request conditioned on the key
1805
    switch(key.as<subdev_prop_t>()){
1806
    case SUBDEV_PROP_NAME:
1807
        val = get_rx_id().to_pp_string();
1808
        return;
1809

    
1810
    case SUBDEV_PROP_OTHERS:
1811
        val = prop_names_t(); //empty
1812
        return;
1813

    
1814
    case SUBDEV_PROP_GAIN:
1815
        assert_has(_gains.keys(), key.name, "tvrx2 gain name");
1816
        val = _gains[key.name];
1817
        return;
1818

    
1819
    case SUBDEV_PROP_GAIN_RANGE:
1820
        assert_has(tvrx2_gain_ranges.keys(), key.name, "tvrx2 gain name");
1821
        val = tvrx2_gain_ranges[key.name];
1822
        return;
1823

    
1824
    case SUBDEV_PROP_GAIN_NAMES:
1825
        val = prop_names_t(tvrx2_gain_ranges.keys());
1826
        return;
1827

    
1828
    case SUBDEV_PROP_FREQ:
1829
        val = _lo_freq;
1830
        return;
1831

    
1832
    case SUBDEV_PROP_FREQ_RANGE:
1833
        val = tvrx2_freq_range;
1834
        return;
1835

    
1836
    case SUBDEV_PROP_ANTENNA:
1837
        val = tvrx2_sd_name_to_antennas[get_subdev_name()];
1838
        return;
1839

    
1840
    case SUBDEV_PROP_ANTENNA_NAMES:
1841
        val = prop_names_t(1, tvrx2_sd_name_to_antennas[get_subdev_name()]);
1842
        return;
1843

    
1844
    case SUBDEV_PROP_CONNECTION:
1845
        val = tvrx2_sd_name_to_conn[get_subdev_name()];
1846
        return;
1847

    
1848
    case SUBDEV_PROP_ENABLED:
1849
        val = _enabled;
1850
        return;
1851

    
1852
    case SUBDEV_PROP_USE_LO_OFFSET:
1853
        val = false;
1854
        return;
1855

    
1856
    case SUBDEV_PROP_SENSOR:
1857
        if (key.name == "lo_locked")
1858
            val = sensor_value_t("LO", this->get_locked(), "locked", "unlocked");
1859
        else if (key.name == "rssi")
1860
            val = sensor_value_t("RSSI", this->get_rssi(), "dBm");
1861
        else if (key.name == "temperature")
1862
            val = sensor_value_t("TEMP", this->get_temp(), "degC");
1863
        else
1864
            UHD_THROW_INVALID_CODE_PATH();
1865
        return;
1866

    
1867
    case SUBDEV_PROP_SENSOR_NAMES:{
1868
            prop_names_t names = list_of("lo_locked")("rssi")("temperature");
1869
            val = names;
1870
        }
1871
        return;
1872

    
1873
    case SUBDEV_PROP_BANDWIDTH:
1874
        val = _bandwidth;
1875
        return;
1876

    
1877
    default: UHD_THROW_PROP_GET_ERROR();
1878
    }
1879
}
1880

    
1881
void tvrx2::rx_set(const wax::obj &key_, const wax::obj &val){
1882
    named_prop_t key = named_prop_t::extract(key_);
1883

    
1884
    //handle the get request conditioned on the key
1885
    switch(key.as<subdev_prop_t>()){
1886

    
1887
    case SUBDEV_PROP_FREQ:
1888
        this->set_lo_freq(val.as<double>());
1889
        return;
1890

    
1891
    case SUBDEV_PROP_GAIN:
1892
        this->set_gain( val.as<double>(), key.name);
1893
        return;
1894

    
1895
    case SUBDEV_PROP_ANTENNA:
1896
        return;
1897

    
1898
    case SUBDEV_PROP_ENABLED:
1899
        if ((val.as<bool>())) this->set_enabled();
1900
        else if (not (val.as<bool>())) this->set_disabled();
1901

    
1902
        return;
1903

    
1904
    case SUBDEV_PROP_BANDWIDTH:
1905
        this->set_bandwidth(val.as<double>());
1906
        return;
1907

    
1908
    default: UHD_THROW_PROP_SET_ERROR();
1909
    }
1910
}
1911