aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/tuner-simple.c
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2006-01-15 12:04:52 -0500
committerMauro Carvalho Chehab <mchehab@brturbo.com.br>2006-01-15 18:25:32 -0500
commit27487d44712aaa37710cc508d5bd6119f5e9f976 (patch)
tree474acfb51469cc730cd76ebdf6f34680b3809442 /drivers/media/video/tuner-simple.c
parent8f0bb9c069fc487dadebe4cdd1e03f0df5ebf0e6 (diff)
V4L/DVB (3384): Separate tv & radio freqs, fix cb/freq transmit order for tuners that need this.
- Moved MSP_SET_MATRIX to v4l2-common.h - Fix typos and integer overflows in tea5767.c - Split old freq field into a tv_freq and a radio_freq. Prevents that a radio tuner is initialized with a tv frequency or vice versa. - When switching to radio mode initialize the tuner with the last used radio frequency (this was already done for the TV mode). As a result of these changes the tuner module now remembers the last set radio and TV frequencies, which is what you would expect to happen. - Move out of range frequencies to the closest valid frequency as per v4l2 API spec. - Fix incorrect initial radio frequency (multiplier is 16000, not 16) - Add boundary check for out of range frequencies. - Use new flag to check if the order of the CB and freq. depends on the last set frequency. That is needed for some tuners or you can get static as a result. The flag is added for those tuners where I know that the datasheet indicates that this is necessary. - For this new check use the last set div value, not the last frequency as radio frequencies are always much higher due to the 16000 multiplier. Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/tuner-simple.c')
-rw-r--r--drivers/media/video/tuner-simple.c44
1 files changed, 23 insertions, 21 deletions
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c
index 3879262cf4ca..37977ff49780 100644
--- a/drivers/media/video/tuner-simple.c
+++ b/drivers/media/video/tuner-simple.c
@@ -136,7 +136,7 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
136 u8 config, tuneraddr; 136 u8 config, tuneraddr;
137 u16 div; 137 u16 div;
138 struct tunertype *tun; 138 struct tunertype *tun;
139 unsigned char buffer[4]; 139 u8 buffer[4];
140 int rc, IFPCoff, i, j; 140 int rc, IFPCoff, i, j;
141 141
142 tun = &tuners[t->type]; 142 tun = &tuners[t->type];
@@ -147,6 +147,11 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
147 continue; 147 continue;
148 break; 148 break;
149 } 149 }
150 if (i == tun->params[j].count) {
151 tuner_dbg("TV frequency out of range (%d > %d)",
152 freq, tun->params[j].ranges[i - 1].limit);
153 freq = tun->params[j].ranges[--i].limit;
154 }
150 config = tun->params[j].ranges[i].cb; 155 config = tun->params[j].ranges[i].cb;
151 /* i == 0 -> VHF_LO */ 156 /* i == 0 -> VHF_LO */
152 /* i == 1 -> VHF_HI */ 157 /* i == 1 -> VHF_HI */
@@ -239,20 +244,6 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
239 break; 244 break;
240 } 245 }
241 246
242 /*
243 * Philips FI1216MK2 remark from specification :
244 * for channel selection involving band switching, and to ensure
245 * smooth tuning to the desired channel without causing
246 * unnecessary charge pump action, it is recommended to consider
247 * the difference between wanted channel frequency and the
248 * current channel frequency. Unnecessary charge pump action
249 * will result in very low tuning voltage which may drive the
250 * oscillator to extreme conditions.
251 *
252 * Progfou: specification says to send config data before
253 * frequency in case (wanted frequency < current frequency).
254 */
255
256 /* IFPCoff = Video Intermediate Frequency - Vif: 247 /* IFPCoff = Video Intermediate Frequency - Vif:
257 940 =16*58.75 NTSC/J (Japan) 248 940 =16*58.75 NTSC/J (Japan)
258 732 =16*45.75 M/N STD 249 732 =16*45.75 M/N STD
@@ -284,7 +275,7 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
284 offset / 16, offset % 16 * 100 / 16, 275 offset / 16, offset % 16 * 100 / 16,
285 div); 276 div);
286 277
287 if (t->type == TUNER_PHILIPS_SECAM && freq < t->freq) { 278 if (tuners[t->type].params->cb_first_if_lower_freq && div < t->last_div) {
288 buffer[0] = tun->params[j].config; 279 buffer[0] = tun->params[j].config;
289 buffer[1] = config; 280 buffer[1] = config;
290 buffer[2] = (div>>8) & 0x7f; 281 buffer[2] = (div>>8) & 0x7f;
@@ -295,6 +286,7 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
295 buffer[2] = tun->params[j].config; 286 buffer[2] = tun->params[j].config;
296 buffer[3] = config; 287 buffer[3] = config;
297 } 288 }
289 t->last_div = div;
298 tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n", 290 tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
299 buffer[0],buffer[1],buffer[2],buffer[3]); 291 buffer[0],buffer[1],buffer[2],buffer[3]);
300 292
@@ -337,8 +329,8 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
337{ 329{
338 struct tunertype *tun; 330 struct tunertype *tun;
339 struct tuner *t = i2c_get_clientdata(c); 331 struct tuner *t = i2c_get_clientdata(c);
340 unsigned char buffer[4]; 332 u8 buffer[4];
341 unsigned div; 333 u16 div;
342 int rc, j; 334 int rc, j;
343 335
344 tun = &tuners[t->type]; 336 tun = &tuners[t->type];
@@ -374,9 +366,19 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
374 } 366 }
375 buffer[0] = (div>>8) & 0x7f; 367 buffer[0] = (div>>8) & 0x7f;
376 buffer[1] = div & 0xff; 368 buffer[1] = div & 0xff;
369 if (tuners[t->type].params->cb_first_if_lower_freq && div < t->last_div) {
370 buffer[0] = buffer[2];
371 buffer[1] = buffer[3];
372 buffer[2] = (div>>8) & 0x7f;
373 buffer[3] = div & 0xff;
374 } else {
375 buffer[0] = (div>>8) & 0x7f;
376 buffer[1] = div & 0xff;
377 }
377 378
378 tuner_dbg("radio 0x%02x 0x%02x 0x%02x 0x%02x\n", 379 tuner_dbg("radio 0x%02x 0x%02x 0x%02x 0x%02x\n",
379 buffer[0],buffer[1],buffer[2],buffer[3]); 380 buffer[0],buffer[1],buffer[2],buffer[3]);
381 t->last_div = div;
380 382
381 if (4 != (rc = i2c_master_send(c,buffer,4))) 383 if (4 != (rc = i2c_master_send(c,buffer,4)))
382 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); 384 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc);
@@ -390,10 +392,10 @@ int default_tuner_init(struct i2c_client *c)
390 t->type, tuners[t->type].name); 392 t->type, tuners[t->type].name);
391 strlcpy(c->name, tuners[t->type].name, sizeof(c->name)); 393 strlcpy(c->name, tuners[t->type].name, sizeof(c->name));
392 394
393 t->tv_freq = default_set_tv_freq; 395 t->set_tv_freq = default_set_tv_freq;
394 t->radio_freq = default_set_radio_freq; 396 t->set_radio_freq = default_set_radio_freq;
395 t->has_signal = tuner_signal; 397 t->has_signal = tuner_signal;
396 t->is_stereo = tuner_stereo; 398 t->is_stereo = tuner_stereo;
397 t->standby = NULL; 399 t->standby = NULL;
398 400
399 return 0; 401 return 0;