E4000 tuner gain settings

Jochen Arndt j.arndt at sis-germany.com
Fri Jan 24 15:35:42 UTC 2014

After playing around with the E4000 tuner gain settings, I will 
summarize my results.

LNA Gain Enhancement

LNA Gain Enhancement is working in automatic mode but not in manual mode.

To enable LNA enhancement, write 0x05 to register AGC11. This can be 
left unchanged even when enabling manual gain mode.

Required updates for tuner_e4k.c:
  Function e4k_enable_manual_gain():
   Remove or comment the line that disables LNA Enhancement for auto mode
    e4k_reg_set_mask(e4k, E4K_REG_AGC11, 0x7, 0);
  Function e4k_init():
   Pull line out of null condition to enable LNA Enhancement
    e4k_reg_set_mask(e4k, E4K_REG_AGC11, 0x7, E4K_AGC11_LNA_GAIN_ENH | 
(2 << 1));

Automatic Mode

The mixer control register AGC7 defines a threshold value. When 
automatic mixer control is enabled and the LNA gain index reaches the 
threshold value, the high mixer gain of 12 dB will be used. Upon reset, 
the AGC7 register is cleared and the threshold value is never set by the 
RTLSDR library. This results in always using the high mixer gain 
(threshold value 0 corresponds to the lowest LNA gain).

The datasheet recommends writing 0x15 to AGC7. This corresponds to a 
threshold of 15 dB (0x15 >> 1 = 0x0A LNA gain index). A value of 0x1D 
would set the threshold to max. LNA gain.
When LNA Enhancement is enabled, setting the threshold to max. gain is 
not useful. There will be a strong gain increasement step from 25 + 4 = 
29 dB to 25 + 5 + 12 = 42 dB.

Required updates for tuner_e4k.c:
  Function e4k_init():
   Replace the line
    e4k_reg_set_mask(e4k, E4K_REG_AGC7, E4K_AGC7_MIX_GAIN_AUTO, 0);
   with this
    e4k_reg_write(e4k, E4K_REG_AGC7, 0x14);

The above modification will set the threshold value and disable auto 
mixer gain control. e4k_enable_manual_gain() is called later and will 
modify only bit 0 of AGC7.

Manual Mode

In manual mode LNA enhancement is not used. So the list of gains must be 
changed because the last two values assume that it is used.

The actually used gains are based on Table 6 and the register map of the 
E4000 data sheet. The gain table contains those values plus the mixer 
gain of 12 db for the last value and 4 db for all others. But the LNA 
gain of 30 dB specified in the data sheet is only valid when LNA gain 
enhancement is enabled.
Cite from data sheet section 1.16 LNA Gain enhancement referring 
register AGC7:
  "The LNA gain numbers quoted throughout this document assume that this
   register is programmed to the recommended value."
Even when LNA Enhancement would work with manual mode, the second to 
last value is wrong because LNA enhancement requires that the mixer gain 
is at 12 dB.

Required updates for librtlsdr.c:
  Change int e4k_gains[]  from
   const int e4k_gains[] = {
    -10, 15, 40, 65, 90, 115, 140, 165, 190, 215, 240, 290, 340, 420
   const int e4k_gains[] = {
	-50 + 40, -25 + 40, 0 + 40, 25 + 40, 50 + 40, 75 + 40,
	100 + 40, 125 + 40, 150 + 40, 175 + 40, 200 + 40, 250 + 40,
	200 + 120,	// 320, optional additional entry
	250 + 120

  Change top of e4000_set_gain() function from
   int e4000_set_gain(void *dev, int gain) {
	rtlsdr_dev_t* devt = (rtlsdr_dev_t*)dev;
	int mixgain = (gain > 340) ? 12 : 4;
	if(e4k_set_lna_gain(&devt->e4k_s, min(300, gain - mixgain * 10)) == 
   int e4000_set_gain(void *dev, int gain) {
	rtlsdr_dev_t* devt = (rtlsdr_dev_t*)dev;
	int mixgain = (0 == (gain - 120) % 25) ? 12 : 4;
	if(e4k_set_lna_gain(&devt->e4k_s, gain - mixgain * 10) == -EINVAL)

The above extraction of the mixer gain from the combined LNA and mixer 
gain can be used for all possible valid LNA/mixer gain combinations.

Required updates for tuner_e4k.c:
  Change last value of static const int32_t lnagain[] from 300 to 250
  Optionally change second to last value from 250 to 249 to force
   selection of the highest possible LNA gain index.

The 2-dim array may be also replaced by a smaller 1-dim array
  when updating also e4k_set_lna_gain():
static const int32_t lna_gain[16] = {
	-50, -25, -50, -25, 0, 25, 50, 75,
	100, 125, 150, 175, 200, 249, 250, 250
int e4k_set_lna_gain(struct e4k_state *e4k, int32_t gain)
	uint32_t i;
	for(i = 0; i < ARRAY_SIZE(lnagain); ++i) {
		if(lnagain[i] == gain) {
			e4k_reg_set_mask(e4k, E4K_REG_GAIN1, 0xf, i);
			return gain;
	return -EINVAL;

Detecting Signal Strength

The signal strength can be calculated by determining the relative 
strength of a signal (e.g. using a FFT) and subtracting the total gain.

To get the total gain in automatic mode, read the registers 0x14 to 0x17
(E4K_REG_GAIN1 to E4K_REG_GAIN4) and calculate the gains. Note again 
that the max. LNA gain of 30 dB is only valid when LNA enhancement is 
enabled and the mixer gain is at 12 dB. Otherwise, the max. LNA gain is 
25 dB.

For signals in the range of -50 to -10 dBm, the RSSI indicator can be 
also read from register 0x1C (E4K_REG_AGC3) in automatic mode to 
calculate the input power in dBm:
  double InputPower = 10 * log10(RSSI)) - 28.5 - LNA_Gain;
The above calculation can be used when the RSSI value is in the range 
from 5 to 24. Higher RSSI values occur with strong signals at min. LNA 
gain and give too low results due to clipped signals.

Jochen Arndt

More information about the osmocom-sdr mailing list