Commit 5e082f15 authored by Trent Piepho's avatar Trent Piepho Committed by Mauro Carvalho Chehab

V4L/DVB (5978): tuner: Better tuner radio support

Add radio support for the Thomson DTT7612 tuner.

This tuner uses a different 1st intermediate frequency than the other radio
tuners supported (a lot of NTSC radio tuners probably need this change too).

Add a new tuner-simple parameter, radio_if.  It selects the 1st IF used for
radio reception.  The radio frequency setting code in tuner-simple now uses
this field, instead of a special case select() block for each tuner with radio
support.

The tuner parameters for tuners that used a 33.3 MHz RIF now set radio_if to 1
in tuner-types.c.

The Thomson DTT7612 gets radio_if = 2, also add has_tda9887 = 1 and
fm_gain_normal = 1.

Add some defines for tda9887 bits that control IF setting in radio mode.

Add a new tda9887 config option, TDA9887_RIF_41_3, that selects a 41.3 MHz
radio IF.

Fix the way tda9887 radio options work.  The driver was modifying the default
radio mode config templates based on the TDA9887_XXXX flags.  This means that
_all_ tuners would get the same settings.  If you had a one tuner than used
TDA9887_GAIN_NORMAL and one that didn't, both would get the setting.  Now the
tda9987 driver just checks if tuner mode is radio and then applies the config
settings directly to the data being sent, just like how all the TV mode
settings already work.

The PLL setting math is made a little more accurate.

And a grammar error in a printk is fixed.
Signed-off-by: default avatarTrent Piepho <xyzzy@speakeasy.org>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent a75d2048
...@@ -97,6 +97,8 @@ struct tvnorm { ...@@ -97,6 +97,8 @@ struct tvnorm {
#define cAudioIF_6_5 0x03 // bit e0:1 #define cAudioIF_6_5 0x03 // bit e0:1
#define cVideoIFMask 0x1c // bit e2:4
/* Video IF selection in TV Mode (bit B3=0) */
#define cVideoIF_58_75 0x00 // bit e2:4 #define cVideoIF_58_75 0x00 // bit e2:4
#define cVideoIF_45_75 0x04 // bit e2:4 #define cVideoIF_45_75 0x04 // bit e2:4
#define cVideoIF_38_90 0x08 // bit e2:4 #define cVideoIF_38_90 0x08 // bit e2:4
...@@ -106,6 +108,13 @@ struct tvnorm { ...@@ -106,6 +108,13 @@ struct tvnorm {
#define cRadioIF_45_75 0x18 // bit e2:4 #define cRadioIF_45_75 0x18 // bit e2:4
#define cRadioIF_38_90 0x1C // bit e2:4 #define cRadioIF_38_90 0x1C // bit e2:4
/* IF1 selection in Radio Mode (bit B3=1) */
#define cRadioIF_33_30 0x00 // bit e2,4 (also 0x10,0x14)
#define cRadioIF_41_30 0x04 // bit e2,4
/* Output of AFC pin in radio mode when bit E7=1 */
#define cRadioAGC_SIF 0x00 // bit e3
#define cRadioAGC_FM 0x08 // bit e3
#define cTunerGainNormal 0x00 // bit e5 #define cTunerGainNormal 0x00 // bit e5
#define cTunerGainLow 0x20 // bit e5 #define cTunerGainLow 0x20 // bit e5
...@@ -487,9 +496,13 @@ static int tda9887_set_config(struct tuner *t, char *buf) ...@@ -487,9 +496,13 @@ static int tda9887_set_config(struct tuner *t, char *buf)
if (t->tda9887_config & TDA9887_GATING_18) if (t->tda9887_config & TDA9887_GATING_18)
buf[3] &= ~cGating_36; buf[3] &= ~cGating_36;
if (t->tda9887_config & TDA9887_GAIN_NORMAL) { if (t->mode == V4L2_TUNER_RADIO) {
radio_stereo.e &= ~cTunerGainLow; if (t->tda9887_config & TDA9887_RIF_41_3) {
radio_mono.e &= ~cTunerGainLow; buf[3] &= ~cVideoIFMask;
buf[3] |= cRadioIF_41_30;
}
if (t->tda9887_config & TDA9887_GAIN_NORMAL)
buf[3] &= ~cTunerGainLow;
} }
return 0; return 0;
......
...@@ -402,53 +402,68 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq) ...@@ -402,53 +402,68 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
u8 buffer[4]; u8 buffer[4];
u16 div; u16 div;
int rc, j; int rc, j;
enum param_type desired_type = TUNER_PARAM_TYPE_RADIO;
struct tuner_params *params; struct tuner_params *params;
tun = &tuners[t->type]; tun = &tuners[t->type];
for (j = 0; j < tun->count-1; j++) { for (j = tun->count-1; j > 0; j--)
if (desired_type != tun->params[j].type) if (tun->params[j].type == TUNER_PARAM_TYPE_RADIO)
continue;
break; break;
} /* default params (j=0) will be used if desired type wasn't found */
/* use default tuner_params if desired_type not available */
if (desired_type != tun->params[j].type)
j = 0;
div = (20 * freq / 16000) + (int)(20*10.7); /* IF 10.7 MHz */
params = &tun->params[j]; params = &tun->params[j];
buffer[2] = (params->ranges[0].config & ~TUNER_RATIO_MASK) | TUNER_RATIO_SELECT_50; /* 50 kHz step */
/* Select Radio 1st IF used */
switch (params->radio_if) {
case 0: /* 10.7 MHz */
freq += (unsigned int)(10.7*16000);
break;
case 1: /* 33.3 MHz */
freq += (unsigned int)(33.3*16000);
break;
case 2: /* 41.3 MHz */
freq += (unsigned int)(41.3*16000);
break;
default:
tuner_warn("Unsupported radio_if value %d\n", params->radio_if);
return;
}
/* Bandswitch byte */
switch (t->type) { switch (t->type) {
case TUNER_TENA_9533_DI: case TUNER_TENA_9533_DI:
case TUNER_YMEC_TVF_5533MF: case TUNER_YMEC_TVF_5533MF:
tuner_dbg ("This tuner doesn't have FM. Most cards has a TEA5767 for FM\n"); tuner_dbg ("This tuner doesn't have FM. Most cards have a TEA5767 for FM\n");
return; return;
case TUNER_PHILIPS_FM1216ME_MK3: case TUNER_PHILIPS_FM1216ME_MK3:
case TUNER_PHILIPS_FM1236_MK3: case TUNER_PHILIPS_FM1236_MK3:
case TUNER_PHILIPS_FMD1216ME_MK3: case TUNER_PHILIPS_FMD1216ME_MK3:
case TUNER_LG_NTSC_TAPE: case TUNER_LG_NTSC_TAPE:
case TUNER_PHILIPS_FM1256_IH3:
buffer[3] = 0x19; buffer[3] = 0x19;
break; break;
case TUNER_TNF_5335MF: case TUNER_TNF_5335MF:
buffer[3] = 0x11; buffer[3] = 0x11;
break; break;
case TUNER_PHILIPS_FM1256_IH3:
div = (20 * freq) / 16000 + (int)(33.3 * 20); /* IF 33.3 MHz */
buffer[3] = 0x19;
break;
case TUNER_LG_PAL_FM: case TUNER_LG_PAL_FM:
buffer[3] = 0xa5; buffer[3] = 0xa5;
break; break;
case TUNER_MICROTUNE_4049FM5: case TUNER_THOMSON_DTT761X:
div = (20 * freq) / 16000 + (int)(33.3 * 20); /* IF 33.3 MHz */ buffer[3] = 0x39;
buffer[3] = 0xa4;
break; break;
case TUNER_MICROTUNE_4049FM5:
default: default:
buffer[3] = 0xa4; buffer[3] = 0xa4;
break; break;
} }
buffer[2] = (params->ranges[0].config & ~TUNER_RATIO_MASK) |
TUNER_RATIO_SELECT_50; /* 50 kHz step */
/* Convert from 1/16 kHz V4L steps to 1/20 MHz (=50 kHz) PLL steps
freq * (1 Mhz / 16000 V4L steps) * (20 PLL steps / 1 MHz) =
freq * (1/800) */
div = (freq + 400) / 800;
if (params->cb_first_if_lower_freq && div < t->last_div) { if (params->cb_first_if_lower_freq && div < t->last_div) {
buffer[0] = buffer[2]; buffer[0] = buffer[2];
buffer[1] = buffer[3]; buffer[1] = buffer[3];
...@@ -475,6 +490,8 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq) ...@@ -475,6 +490,8 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
config &= ~TDA9887_PORT1_ACTIVE;*/ config &= ~TDA9887_PORT1_ACTIVE;*/
if (params->fm_gain_normal) if (params->fm_gain_normal)
config |= TDA9887_GAIN_NORMAL; config |= TDA9887_GAIN_NORMAL;
if (params->radio_if == 2)
config |= TDA9887_RIF_41_3;
i2c_clients_command(c->adapter, TDA9887_SET_CONFIG, &config); i2c_clients_command(c->adapter, TDA9887_SET_CONFIG, &config);
} }
if (4 != (rc = i2c_master_send(c,buffer,4))) if (4 != (rc = i2c_master_send(c,buffer,4)))
......
...@@ -652,6 +652,7 @@ static struct tuner_params tuner_microtune_4049_fm5_params[] = { ...@@ -652,6 +652,7 @@ static struct tuner_params tuner_microtune_4049_fm5_params[] = {
.port1_invert_for_secam_lc = 1, .port1_invert_for_secam_lc = 1,
.default_pll_gating_18 = 1, .default_pll_gating_18 = 1,
.fm_gain_normal=1, .fm_gain_normal=1,
.radio_if = 1, /* 33.3 MHz */
}, },
}; };
...@@ -733,6 +734,7 @@ static struct tuner_params tuner_philips_fm1256_ih3_params[] = { ...@@ -733,6 +734,7 @@ static struct tuner_params tuner_philips_fm1256_ih3_params[] = {
.type = TUNER_PARAM_TYPE_PAL, .type = TUNER_PARAM_TYPE_PAL,
.ranges = tuner_fm1236_mk3_ntsc_ranges, .ranges = tuner_fm1236_mk3_ntsc_ranges,
.count = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges), .count = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges),
.radio_if = 1, /* 33.3 MHz */
}, },
}; };
...@@ -859,6 +861,9 @@ static struct tuner_params tuner_thomson_dtt761x_params[] = { ...@@ -859,6 +861,9 @@ static struct tuner_params tuner_thomson_dtt761x_params[] = {
.type = TUNER_PARAM_TYPE_NTSC, .type = TUNER_PARAM_TYPE_NTSC,
.ranges = tuner_thomson_dtt761x_ntsc_ranges, .ranges = tuner_thomson_dtt761x_ntsc_ranges,
.count = ARRAY_SIZE(tuner_thomson_dtt761x_ntsc_ranges), .count = ARRAY_SIZE(tuner_thomson_dtt761x_ntsc_ranges),
.has_tda9887 = 1,
.fm_gain_normal = 1,
.radio_if = 2, /* 41.3 MHz */
}, },
}; };
......
...@@ -79,6 +79,10 @@ struct tuner_params { ...@@ -79,6 +79,10 @@ struct tuner_params {
/* Select 18% (or according to datasheet 0%) L standard PLL gating, /* Select 18% (or according to datasheet 0%) L standard PLL gating,
vs the driver default of 36%. */ vs the driver default of 36%. */
unsigned int default_pll_gating_18:1; unsigned int default_pll_gating_18:1;
/* IF to use in radio mode. Tuners with a separate radio IF filter
seem to use 10.7, while those without use 33.3 for PAL/SECAM tuners
and 41.3 for NTSC tuners. 0 = 10.7, 1 = 33.3, 2 = 41.3 */
unsigned int radio_if:2;
/* Default tda9887 TOP value in dB for the low band. Default is 0. /* Default tda9887 TOP value in dB for the low band. Default is 0.
Range: -16:+15 */ Range: -16:+15 */
signed int default_top_low:5; signed int default_top_low:5;
......
...@@ -146,6 +146,7 @@ extern int tuner_debug; ...@@ -146,6 +146,7 @@ extern int tuner_debug;
#define TDA9887_AUTOMUTE (1<<18) #define TDA9887_AUTOMUTE (1<<18)
#define TDA9887_GATING_18 (1<<19) #define TDA9887_GATING_18 (1<<19)
#define TDA9887_GAIN_NORMAL (1<<20) #define TDA9887_GAIN_NORMAL (1<<20)
#define TDA9887_RIF_41_3 (1<<21) /* radio IF1 41.3 vs 33.3 */
#ifdef __KERNEL__ #ifdef __KERNEL__
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment