diff options
Diffstat (limited to 'drivers/media/video/tuner-simple.c')
-rw-r--r-- | drivers/media/video/tuner-simple.c | 44 |
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; |