Skip to content

Commit

Permalink
V4L/DVB (4270): Add tda9887-specific tuner configuration
Browse files Browse the repository at this point in the history
Many tda9887 settings depend on the chosen tuner. Expand the tuner parameters
to include these tda9887 settings.

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
  • Loading branch information
Hans Verkuil authored and Mauro Carvalho Chehab committed Jun 30, 2006
1 parent 0a11537 commit ba8fc39
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 13 deletions.
4 changes: 2 additions & 2 deletions drivers/media/video/tda9887.c
Original file line number Diff line number Diff line change
Expand Up @@ -590,8 +590,8 @@ int tda9887_tuner_init(struct i2c_client *c)
t->set_tv_freq = tda9887_set_freq;
t->set_radio_freq = tda9887_set_freq;
t->standby = tda9887_standby;
t->tuner_status=tda9887_tuner_status;
t->get_afc=tda9887_get_afc;
t->tuner_status = tda9887_tuner_status;
t->get_afc = tda9887_get_afc;

return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/media/video/tuner-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ static void tuner_status(struct i2c_client *client)

/* ---------------------------------------------------------------------- */

/* static var Used only in tuner_attach and tuner_probe */
/* static vars: used only in tuner_attach and tuner_probe */
static unsigned default_mode_mask;

/* During client attach, set_type is called by adapter's attach_inform callback.
Expand Down
74 changes: 64 additions & 10 deletions drivers/media/video/tuner-simple.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <linux/i2c.h>
#include <linux/videodev.h>
#include <media/tuner.h>
#include <media/v4l2-common.h>

static int offset = 0;
module_param(offset, int, 0666);
Expand Down Expand Up @@ -128,6 +129,7 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
u8 buffer[4];
int rc, IFPCoff, i, j;
enum param_type desired_type;
struct tuner_params *params;

tun = &tuners[t->type];

Expand Down Expand Up @@ -169,19 +171,20 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
IFPCoff,t->type);
j = 0;
}
params = &tun->params[j];

for (i = 0; i < tun->params[j].count; i++) {
if (freq > tun->params[j].ranges[i].limit)
for (i = 0; i < params->count; i++) {
if (freq > params->ranges[i].limit)
continue;
break;
}
if (i == tun->params[j].count) {
if (i == params->count) {
tuner_dbg("TV frequency out of range (%d > %d)",
freq, tun->params[j].ranges[i - 1].limit);
freq = tun->params[j].ranges[--i].limit;
freq, params->ranges[i - 1].limit);
freq = params->ranges[--i].limit;
}
config = tun->params[j].ranges[i].config;
cb = tun->params[j].ranges[i].cb;
config = params->ranges[i].config;
cb = params->ranges[i].cb;
/* i == 0 -> VHF_LO
* i == 1 -> VHF_HI
* i == 2 -> UHF */
Expand Down Expand Up @@ -281,7 +284,7 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
break;
}

if (tuners[t->type].params->cb_first_if_lower_freq && div < t->last_div) {
if (params->cb_first_if_lower_freq && div < t->last_div) {
buffer[0] = config;
buffer[1] = cb;
buffer[2] = (div>>8) & 0x7f;
Expand All @@ -293,6 +296,43 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
buffer[3] = cb;
}
t->last_div = div;
if (params->has_tda9887) {
int config = 0;
int is_secam_l = (t->std & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC)) &&
!(t->std & ~(V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC));

if (t->std == V4L2_STD_SECAM_LC) {
if (params->port1_active ^ params->port1_invert_for_secam_lc)
config |= TDA9887_PORT1_ACTIVE;
if (params->port2_active ^ params->port2_invert_for_secam_lc)
config |= TDA9887_PORT2_ACTIVE;
}
else {
if (params->port1_active)
config |= TDA9887_PORT1_ACTIVE;
if (params->port2_active)
config |= TDA9887_PORT2_ACTIVE;
}
if (params->intercarrier_mode)
config |= TDA9887_INTERCARRIER;
if (is_secam_l) {
if (i == 0 && params->default_top_secam_low)
config |= TDA9887_TOP(params->default_top_secam_low);
else if (i == 1 && params->default_top_secam_mid)
config |= TDA9887_TOP(params->default_top_secam_mid);
else if (params->default_top_secam_high)
config |= TDA9887_TOP(params->default_top_secam_high);
}
else {
if (i == 0 && params->default_top_low)
config |= TDA9887_TOP(params->default_top_low);
else if (i == 1 && params->default_top_mid)
config |= TDA9887_TOP(params->default_top_mid);
else if (params->default_top_high)
config |= TDA9887_TOP(params->default_top_high);
}
i2c_clients_command(c->adapter, TDA9887_SET_CONFIG, &config);
}
tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
buffer[0],buffer[1],buffer[2],buffer[3]);

Expand Down Expand Up @@ -339,6 +379,7 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
u16 div;
int rc, j;
enum param_type desired_type = TUNER_PARAM_TYPE_RADIO;
struct tuner_params *params;

tun = &tuners[t->type];

Expand All @@ -352,7 +393,8 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
j = 0;

div = (20 * freq / 16000) + (int)(20*10.7); /* IF 10.7 MHz */
buffer[2] = (tun->params[j].ranges[0].config & ~TUNER_RATIO_MASK) | TUNER_RATIO_SELECT_50; /* 50 kHz step */
params = &tun->params[j];
buffer[2] = (params->ranges[0].config & ~TUNER_RATIO_MASK) | TUNER_RATIO_SELECT_50; /* 50 kHz step */

switch (t->type) {
case TUNER_TENA_9533_DI:
Expand Down Expand Up @@ -384,7 +426,7 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
}
buffer[0] = (div>>8) & 0x7f;
buffer[1] = div & 0xff;
if (tuners[t->type].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[1] = buffer[3];
buffer[2] = (div>>8) & 0x7f;
Expand All @@ -398,6 +440,18 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
buffer[0],buffer[1],buffer[2],buffer[3]);
t->last_div = div;

if (params->has_tda9887) {
int config = 0;
if (params->port1_active && !params->port1_fm_high_sensitivity)
config |= TDA9887_PORT1_ACTIVE;
if (params->port2_active && !params->port2_fm_high_sensitivity)
config |= TDA9887_PORT2_ACTIVE;
if (params->intercarrier_mode)
config |= TDA9887_INTERCARRIER;
/* if (params->port1_set_for_fm_mono)
config &= ~TDA9887_PORT1_ACTIVE;*/
i2c_clients_command(c->adapter, TDA9887_SET_CONFIG, &config);
}
if (4 != (rc = i2c_master_send(c,buffer,4)))
tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc);
}
Expand Down
38 changes: 38 additions & 0 deletions drivers/media/video/tuner-types.c
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,10 @@ static struct tuner_params tuner_philips_fq1216me_params[] = {
.type = TUNER_PARAM_TYPE_PAL,
.ranges = tuner_lg_pal_ranges,
.count = ARRAY_SIZE(tuner_lg_pal_ranges),
.has_tda9887 = 1,
.port1_active = 1,
.port2_active = 1,
.port2_invert_for_secam_lc = 1,
},
};

Expand Down Expand Up @@ -542,6 +546,14 @@ static struct tuner_params tuner_fm1216me_mk3_params[] = {
.ranges = tuner_fm1216me_mk3_pal_ranges,
.count = ARRAY_SIZE(tuner_fm1216me_mk3_pal_ranges),
.cb_first_if_lower_freq = 1,
.has_tda9887 = 1,
.port1_active = 1,
.port2_active = 1,
.port2_invert_for_secam_lc = 1,
.port1_fm_high_sensitivity = 1,
.default_top_mid = -2,
.default_top_secam_mid = -2,
.default_top_secam_high = -2,
},
};

Expand Down Expand Up @@ -612,6 +624,10 @@ static struct tuner_params tuner_fm1236_mk3_params[] = {
.ranges = tuner_fm1236_mk3_ntsc_ranges,
.count = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges),
.cb_first_if_lower_freq = 1,
.has_tda9887 = 1,
.port1_active = 1,
.port2_active = 1,
.port1_fm_high_sensitivity = 1,
},
};

Expand All @@ -632,6 +648,8 @@ static struct tuner_params tuner_microtune_4049_fm5_params[] = {
.type = TUNER_PARAM_TYPE_PAL,
.ranges = tuner_temic_4009f_5_pal_ranges,
.count = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges),
.has_tda9887 = 1,
.port1_invert_for_secam_lc = 1,
},
};

Expand All @@ -648,6 +666,8 @@ static struct tuner_params tuner_panasonic_vp27_params[] = {
.type = TUNER_PARAM_TYPE_NTSC,
.ranges = tuner_panasonic_vp27_ntsc_ranges,
.count = ARRAY_SIZE(tuner_panasonic_vp27_ntsc_ranges),
.has_tda9887 = 1,
.intercarrier_mode = 1,
},
};

Expand Down Expand Up @@ -782,6 +802,13 @@ static struct tuner_params tuner_philips_fq1216ame_mk4_params[] = {
.type = TUNER_PARAM_TYPE_PAL,
.ranges = tuner_philips_fq12_6a___mk4_pal_ranges,
.count = ARRAY_SIZE(tuner_philips_fq12_6a___mk4_pal_ranges),
.has_tda9887 = 1,
.port1_active = 1,
.port2_invert_for_secam_lc = 1,
.default_top_mid = -2,
.default_top_secam_low = -2,
.default_top_secam_mid = -2,
.default_top_secam_high = -2,
},
};

Expand Down Expand Up @@ -870,6 +897,12 @@ static struct tuner_params tuner_philips_fmd1216me_mk3_params[] = {
.type = TUNER_PARAM_TYPE_PAL,
.ranges = tuner_philips_fmd1216me_mk3_pal_ranges,
.count = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_pal_ranges),
.has_tda9887 = 1,
.port1_active = 1,
.port2_active = 1,
.port2_fm_high_sensitivity = 1,
.port2_invert_for_secam_lc = 1,
.port1_set_for_fm_mono = 1,
},
};

Expand Down Expand Up @@ -1005,6 +1038,7 @@ static struct tuner_params tuner_samsung_tcpn_2121p30a_params[] = {
.type = TUNER_PARAM_TYPE_NTSC,
.ranges = tuner_samsung_tcpn_2121p30a_ntsc_ranges,
.count = ARRAY_SIZE(tuner_samsung_tcpn_2121p30a_ntsc_ranges),
.has_tda9887 = 1,
},
};

Expand Down Expand Up @@ -1037,6 +1071,10 @@ static struct tuner_params tuner_samsung_tcpg_6121p30a_params[] = {
.type = TUNER_PARAM_TYPE_PAL,
.ranges = tuner_samsung_tcpg_6121p30a_pal_ranges,
.count = ARRAY_SIZE(tuner_samsung_tcpg_6121p30a_pal_ranges),
.has_tda9887 = 1,
.port1_active = 1,
.port2_active = 1,
.port2_invert_for_secam_lc = 1,
},
};

Expand Down
55 changes: 55 additions & 0 deletions include/media/tuner-types.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ struct tuner_range {

struct tuner_params {
enum param_type type;

/* Many Philips based tuners have a comment like this in their
* datasheet:
*
Expand All @@ -39,6 +40,60 @@ struct tuner_params {
* static unless the control byte was sent first.
*/
unsigned int cb_first_if_lower_freq:1;
/* Set to 1 if this tuner uses a tda9887 */
unsigned int has_tda9887:1;
/* Many Philips tuners use tda9887 PORT1 to select the FM radio
sensitivity. If this setting is 1, then set PORT1 to 1 to
get proper FM reception. */
unsigned int port1_fm_high_sensitivity:1;
/* Some Philips tuners use tda9887 PORT2 to select the FM radio
sensitivity. If this setting is 1, then set PORT2 to 1 to
get proper FM reception. */
unsigned int port2_fm_high_sensitivity:1;
/* Most tuners with a tda9887 use QSS mode. Some (cheaper) tuners
use Intercarrier mode. If this setting is 1, then the tuner
needs to be set to intercarrier mode. */
unsigned int intercarrier_mode:1;
/* This setting sets the default value for PORT1.
0 means inactive, 1 means active. Note: the actual bit
value written to the tda9887 is inverted. So a 0 here
means a 1 in the B6 bit. */
unsigned int port1_active:1;
/* This setting sets the default value for PORT2.
0 means inactive, 1 means active. Note: the actual bit
value written to the tda9887 is inverted. So a 0 here
means a 1 in the B7 bit. */
unsigned int port2_active:1;
/* Sometimes PORT1 is inverted when the SECAM-L' standard is selected.
Set this bit to 1 if this is needed. */
unsigned int port1_invert_for_secam_lc:1;
/* Sometimes PORT2 is inverted when the SECAM-L' standard is selected.
Set this bit to 1 if this is needed. */
unsigned int port2_invert_for_secam_lc:1;
/* Some cards require PORT1 to be 1 for mono Radio FM and 0 for stereo. */
unsigned int port1_set_for_fm_mono:1;
/* Default tda9887 TOP value in dB for the low band. Default is 0.
Range: -16:+15 */
signed int default_top_low:5;
/* Default tda9887 TOP value in dB for the mid band. Default is 0.
Range: -16:+15 */
signed int default_top_mid:5;
/* Default tda9887 TOP value in dB for the high band. Default is 0.
Range: -16:+15 */
signed int default_top_high:5;
/* Default tda9887 TOP value in dB for SECAM-L/L' for the low band.
Default is 0. Several tuners require a different TOP value for
the SECAM-L/L' standards. Range: -16:+15 */
signed int default_top_secam_low:5;
/* Default tda9887 TOP value in dB for SECAM-L/L' for the mid band.
Default is 0. Several tuners require a different TOP value for
the SECAM-L/L' standards. Range: -16:+15 */
signed int default_top_secam_mid:5;
/* Default tda9887 TOP value in dB for SECAM-L/L' for the high band.
Default is 0. Several tuners require a different TOP value for
the SECAM-L/L' standards. Range: -16:+15 */
signed int default_top_secam_high:5;


unsigned int count;
struct tuner_range *ranges;
Expand Down

0 comments on commit ba8fc39

Please sign in to comment.