@@ -64,6 +64,7 @@ typedef struct rtlsdr_tuner_iface {
6464 int (* set_gain )(void * , int gain /* tenth dB */ );
6565 int (* set_if_gain )(void * , int stage , int gain /* tenth dB */ );
6666 int (* set_gain_mode )(void * , int manual );
67+ int (* set_if_freq )(void * , uint32_t freq /* Hz */ );
6768} rtlsdr_tuner_iface_t ;
6869
6970enum rtlsdr_async_status {
@@ -123,6 +124,7 @@ struct rtlsdr_dev {
123124 int dev_lost ;
124125 int driver_active ;
125126 unsigned int xfer_errors ;
127+ int tuner_initialized ;
126128};
127129
128130void rtlsdr_set_gpio_bit (rtlsdr_dev_t * dev , uint8_t gpio , int val );
@@ -238,7 +240,17 @@ int r820t_set_freq(void *dev, uint32_t freq) {
238240 rtlsdr_dev_t * devt = (rtlsdr_dev_t * )dev ;
239241 return r82xx_set_freq (& devt -> r82xx_p , freq );
240242}
241- int r820t_set_bw (void * dev , int bw ) { return 0 ; }
243+
244+ int r820t_set_bw (void * dev , int bw ) {
245+ rtlsdr_dev_t * devt = (rtlsdr_dev_t * )dev ;
246+ return r82xx_set_bw (& devt -> r82xx_p , bw );
247+ }
248+
249+ int r820t_set_if_freq (void * dev , uint32_t freq ) {
250+ rtlsdr_dev_t * devt = (rtlsdr_dev_t * )dev ;
251+ return r82xx_set_if_freq (& devt -> r82xx_p , freq );
252+ }
253+
242254int r820t_set_gain (void * dev , int gain ) {
243255 rtlsdr_dev_t * devt = (rtlsdr_dev_t * )dev ;
244256 return r82xx_set_gain (& devt -> r82xx_p , 1 , gain );
@@ -251,37 +263,37 @@ int r820t_set_gain_mode(void *dev, int manual) {
251263/* definition order must match enum rtlsdr_tuner */
252264static rtlsdr_tuner_iface_t tuners [] = {
253265 {
254- NULL , NULL , NULL , NULL , NULL , NULL , NULL /* dummy for unknown tuners */
266+ NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL /* dummy for unknown tuners */
255267 },
256268 {
257269 e4000_init , e4000_exit ,
258270 e4000_set_freq , e4000_set_bw , e4000_set_gain , e4000_set_if_gain ,
259- e4000_set_gain_mode
271+ e4000_set_gain_mode , NULL
260272 },
261273 {
262274 _fc0012_init , fc0012_exit ,
263275 fc0012_set_freq , fc0012_set_bw , _fc0012_set_gain , NULL ,
264- fc0012_set_gain_mode
276+ fc0012_set_gain_mode , NULL
265277 },
266278 {
267279 _fc0013_init , fc0013_exit ,
268280 fc0013_set_freq , fc0013_set_bw , _fc0013_set_gain , NULL ,
269- fc0013_set_gain_mode
281+ fc0013_set_gain_mode , NULL
270282 },
271283 {
272284 fc2580_init , fc2580_exit ,
273285 _fc2580_set_freq , fc2580_set_bw , fc2580_set_gain , NULL ,
274- fc2580_set_gain_mode
286+ fc2580_set_gain_mode , NULL
275287 },
276288 {
277289 r820t_init , r820t_exit ,
278290 r820t_set_freq , r820t_set_bw , r820t_set_gain , NULL ,
279- r820t_set_gain_mode
291+ r820t_set_gain_mode , r820t_set_if_freq
280292 },
281293 {
282294 r820t_init , r820t_exit ,
283295 r820t_set_freq , r820t_set_bw , r820t_set_gain , NULL ,
284- r820t_set_gain_mode
296+ r820t_set_gain_mode , r820t_set_if_freq
285297 },
286298};
287299
@@ -662,6 +674,7 @@ int rtlsdr_deinit_baseband(rtlsdr_dev_t *dev)
662674 rtlsdr_set_i2c_repeater (dev , 1 );
663675 r = dev -> tuner -> exit (dev ); /* deinitialize tuner */
664676 rtlsdr_set_i2c_repeater (dev , 0 );
677+ dev -> tuner_initialized = 0 ;
665678 }
666679
667680 /* poweroff demodulator and ADCs */
@@ -693,6 +706,14 @@ int rtlsdr_set_if_freq(rtlsdr_dev_t *dev, uint32_t freq)
693706 tmp = if_freq & 0xff ;
694707 r |= rtlsdr_demod_write_reg (dev , 1 , 0x1b , tmp , 1 );
695708
709+ /* Tell the R820T driver which IF frequency we are currently using
710+ * so that it can choose the optimal IF filter settings.
711+ * Works for normal tuning as well as no-mod direct sampling! */
712+ if (dev -> tuner_initialized && dev -> tuner && dev -> tuner -> set_if_freq ) {
713+ rtlsdr_set_i2c_repeater (dev , 1 );
714+ dev -> tuner -> set_if_freq (dev , freq );
715+ rtlsdr_set_i2c_repeater (dev , 0 );
716+ }
696717 return r ;
697718}
698719
@@ -1144,6 +1165,7 @@ int rtlsdr_set_direct_sampling(rtlsdr_dev_t *dev, int on)
11441165 rtlsdr_set_i2c_repeater (dev , 1 );
11451166 r = dev -> tuner -> exit (dev );
11461167 rtlsdr_set_i2c_repeater (dev , 0 );
1168+ dev -> tuner_initialized = 0 ;
11471169 }
11481170 }
11491171
@@ -1153,6 +1175,7 @@ int rtlsdr_set_direct_sampling(rtlsdr_dev_t *dev, int on)
11531175 fprintf (stderr , "Tuning E4000 to 3708 MHz\n" );
11541176 rtlsdr_set_i2c_repeater (dev , 1 );
11551177 dev -> tuner -> init (dev );
1178+ dev -> tuner_initialized = 1 ;
11561179 dev -> tuner -> set_freq (dev , 3708000000u );
11571180 e4000_set_bw (dev , 15000000 );
11581181 rtlsdr_set_i2c_repeater (dev , 0 );
@@ -1161,6 +1184,7 @@ int rtlsdr_set_direct_sampling(rtlsdr_dev_t *dev, int on)
11611184 rtlsdr_dev_t * devt = (rtlsdr_dev_t * )dev ;
11621185 rtlsdr_set_i2c_repeater (dev , 1 );
11631186 dev -> tuner -> init (dev );
1187+ dev -> tuner_initialized = 1 ;
11641188 r82xx_set_nomod (& devt -> r82xx_p );
11651189 rtlsdr_set_i2c_repeater (dev , 0 );
11661190 }
@@ -1190,11 +1214,12 @@ int rtlsdr_set_direct_sampling(rtlsdr_dev_t *dev, int on)
11901214 rtlsdr_set_i2c_repeater (dev , 1 );
11911215 r |= dev -> tuner -> init (dev );
11921216 rtlsdr_set_i2c_repeater (dev , 0 );
1217+ dev -> tuner_initialized = 1 ;
11931218 }
11941219
11951220 if ((dev -> tuner_type == RTLSDR_TUNER_R820T ) ||
11961221 (dev -> tuner_type == RTLSDR_TUNER_R828D )) {
1197- r |= rtlsdr_set_if_freq (dev , R82XX_IF_FREQ );
1222+ r |= rtlsdr_set_if_freq (dev , R82XX_DEFAULT_IF_FREQ );
11981223
11991224 /* enable spectrum inversion */
12001225 r |= rtlsdr_demod_write_reg (dev , 1 , 0x15 , 0x01 , 1 );
@@ -1585,7 +1610,7 @@ int rtlsdr_open(rtlsdr_dev_t **out_dev, uint32_t index)
15851610
15861611 /* the R82XX use 3.57 MHz IF for the DVB-T 6 MHz mode, and
15871612 * 4.57 MHz for the 8 MHz mode */
1588- rtlsdr_set_if_freq (dev , R82XX_IF_FREQ );
1613+ rtlsdr_set_if_freq (dev , R82XX_DEFAULT_IF_FREQ );
15891614
15901615 /* enable spectrum inversion */
15911616 rtlsdr_demod_write_reg (dev , 1 , 0x15 , 0x01 , 1 );
@@ -1598,8 +1623,10 @@ int rtlsdr_open(rtlsdr_dev_t **out_dev, uint32_t index)
15981623 break ;
15991624 }
16001625
1601- if (dev -> tuner -> init )
1626+ if (dev -> tuner -> init ) {
16021627 r = dev -> tuner -> init (dev );
1628+ dev -> tuner_initialized = 1 ;
1629+ }
16031630
16041631 rtlsdr_set_i2c_repeater (dev , 0 );
16051632
0 commit comments