diff --git a/src/librtlsdr.c b/src/librtlsdr.c index c9e43a1..55d2ef1 100644 --- a/src/librtlsdr.c +++ b/src/librtlsdr.c @@ -1563,7 +1563,12 @@ int rtlsdr_open(rtlsdr_dev_t **out_dev, uint32_t index) reg = rtlsdr_i2c_read_reg(dev, R820T_I2C_ADDR, R82XX_CHECK_ADDR); if (reg == R82XX_CHECK_VAL) { fprintf(stderr, "Found Rafael Micro R820T tuner\n"); + + if (rtlsdr_check_dongle_model(dev, "RTLSDRBlog", "Blog V4L")) + fprintf(stderr, "RTL-SDR Blog V4 Lite Detected\n"); + dev->tuner_type = RTLSDR_TUNER_R820T; + goto found; } diff --git a/src/tuner_r82xx.c b/src/tuner_r82xx.c index 6de6b24..fb4dc9c 100644 --- a/src/tuner_r82xx.c +++ b/src/tuner_r82xx.c @@ -503,7 +503,7 @@ static int r82xx_set_pll(struct r82xx_priv *priv, uint32_t freq) if (rc < 0) return rc; - if (priv->cfg->rafael_chip == CHIP_R828D) + if (priv->cfg->rafael_chip == CHIP_R828D || rtlsdr_check_dongle_model(priv->rtl_dev, "RTLSDRBlog", "Blog V4L")) vco_power_ref = 1; vco_fine_tune = (data[4] & 0x30) >> 4; @@ -1125,6 +1125,7 @@ int r82xx_set_freq(struct r82xx_priv *priv, uint32_t freq) { int rc = -1; int is_rtlsdr_blog_v4; + int is_rtlsdr_blog_v4l; uint32_t upconvert_freq; uint32_t lo_freq; uint8_t air_cable1_in; @@ -1135,10 +1136,11 @@ int r82xx_set_freq(struct r82xx_priv *priv, uint32_t freq) uint8_t air_in; is_rtlsdr_blog_v4 = rtlsdr_check_dongle_model(priv->rtl_dev, "RTLSDRBlog", "Blog V4"); + is_rtlsdr_blog_v4l = rtlsdr_check_dongle_model(priv->rtl_dev, "RTLSDRBlog", "Blog V4L"); /* if it's an RTL-SDR Blog V4, automatically upconvert by 28.8 MHz if we tune to HF * so that we don't need to manually set any upconvert offset in the SDR software */ - upconvert_freq = is_rtlsdr_blog_v4 ? ((freq < MHZ(28.8)) ? (freq + MHZ(28.8)) : freq) : freq; + upconvert_freq = (is_rtlsdr_blog_v4 || is_rtlsdr_blog_v4l) ? ((freq < MHZ(28.8)) ? (freq + MHZ(28.8)) : freq) : freq; lo_freq = upconvert_freq + priv->int_freq; @@ -1164,7 +1166,20 @@ int r82xx_set_freq(struct r82xx_priv *priv, uint32_t freq) *(to avoid excessive register writes when tuning rapidly) */ band = (freq <= MHZ(28.8)) ? HF : ((freq > MHZ(28.8) && freq < MHZ(250)) ? VHF : UHF); - + + /* bypass tracking filter for HF to reduce insertion loss, + * the upconverter path doesn't benefit from it. + * Must be outside band-change guard since r82xx_set_mux + * re-applies the tracking filter on every frequency change. */ + if (band == HF) { + rc = r82xx_write_reg_mask(priv, 0x1a, 0x40, 0xc3); + if (rc < 0) + goto err; + rc = r82xx_write_reg(priv, 0x1b, 0x00); + if (rc < 0) + goto err; + } + /* switch between tuner inputs on the RTL-SDR Blog V4 */ if (band != priv->input) { priv->input = band; @@ -1197,6 +1212,52 @@ int r82xx_set_freq(struct r82xx_priv *priv, uint32_t freq) goto err; } } + else if (is_rtlsdr_blog_v4l) + { + /* select tuner band based on frequency and only switch if there is a band change + *(to avoid excessive register writes when tuning rapidly) + */ + band = (freq <= MHZ(28.8)) ? HF : UHF; + + /* bypass tracking filter for HF to reduce insertion loss, + * the upconverter path doesn't benefit from it. + * Must be outside band-change guard since r82xx_set_mux + * re-applies the tracking filter on every frequency change. */ + if (band == HF) { + rc = r82xx_write_reg_mask(priv, 0x1a, 0x40, 0xc3); + if (rc < 0) + goto err; + rc = r82xx_write_reg(priv, 0x1b, 0x00); + if (rc < 0) + goto err; + } + + /* switch between tuner inputs on the RTL-SDR Blog V4L */ + if (band != priv->input) { + priv->input = band; + + cable_1_in = (band == HF) ? 0x40 : 0x00; + + /* Control upconverter GPIO switch on newer batches */ + rc = rtlsdr_set_bias_tee_gpio(priv->rtl_dev, 5, !cable_1_in); + + if (rc < 0) + goto err; + + /* activate cable 1 (HF input) */ + rc = r82xx_write_reg_mask(priv, 0x05, cable_1_in, 0x40); + + if (rc < 0) + goto err; + + /* activate air_in (UHF input) */ + air_in = (band == UHF) ? 0x00 : 0x20; + rc = r82xx_write_reg_mask(priv, 0x05, air_in, 0x20); + + if (rc < 0) + goto err; + } + } else /* Standard R828D dongle*/ { /* switch between 'Cable1' and 'Air-In' inputs on sticks with