File: /usr/src/linux/drivers/media/video/tuner.c
1 #include <linux/module.h>
2 #include <linux/kernel.h>
3 #include <linux/sched.h>
4 #include <linux/string.h>
5 #include <linux/timer.h>
6 #include <linux/delay.h>
7 #include <linux/errno.h>
8 #include <linux/slab.h>
9 #include <linux/poll.h>
10 #include <linux/i2c.h>
11 #include <linux/types.h>
12 #include <linux/videodev.h>
13 #include <linux/init.h>
14
15 #include "tuner.h"
16 #include "audiochip.h"
17
18 /* Addresses to scan */
19 static unsigned short normal_i2c[] = {I2C_CLIENT_END};
20 static unsigned short normal_i2c_range[] = {0x60,0x6f,I2C_CLIENT_END};
21 static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
22 static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
23 static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
24 static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
25 static unsigned short force[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
26 static struct i2c_client_address_data addr_data = {
27 normal_i2c, normal_i2c_range,
28 probe, probe_range,
29 ignore, ignore_range,
30 force
31 };
32
33 static int debug = 0; /* insmod parameter */
34 static int type = -1; /* insmod parameter */
35
36 static int addr = 0;
37 static char *pal = "b";
38 static int this_adap;
39 static int tv_range[2] = { 44, 958 };
40 static int radio_range[2] = { 65, 108 };
41
42 #define dprintk if (debug) printk
43
44 MODULE_PARM(debug,"i");
45 MODULE_PARM(type,"i");
46 MODULE_PARM(addr,"i");
47 MODULE_PARM(tv_range,"2i");
48 MODULE_PARM(radio_range,"2i");
49 MODULE_PARM(pal,"s");
50
51 struct tuner
52 {
53 int type; /* chip type */
54 int freq; /* keep track of the current settings */
55 int std;
56
57 int radio;
58 int mode; /* PAL(0)/SECAM(1) mode (PHILIPS_SECAM only) */
59 };
60
61 static struct i2c_driver driver;
62 static struct i2c_client client_template;
63
64 /* tv standard selection for Temic 4046 FM5
65 this value takes the low bits of control byte 2
66 from datasheet Rev.01, Feb.00
67 standard BG I L L2 D
68 picture IF 38.9 38.9 38.9 33.95 38.9
69 sound 1 33.4 32.9 32.4 40.45 32.4
70 sound 2 33.16
71 NICAM 33.05 32.348 33.05 33.05
72 */
73 #define TEMIC_SET_PAL_I 0x05
74 #define TEMIC_SET_PAL_DK 0x09
75 #define TEMIC_SET_PAL_L 0x0a // SECAM ?
76 #define TEMIC_SET_PAL_L2 0x0b // change IF !
77 #define TEMIC_SET_PAL_BG 0x0c
78
79 /* tv tuner system standard selection for Philips FQ1216ME
80 this value takes the low bits of control byte 2
81 from datasheet "1999 Nov 16" (supersedes "1999 Mar 23")
82 standard BG DK I L L`
83 picture carrier 38.90 38.90 38.90 38.90 33.95
84 colour 34.47 34.47 34.47 34.47 38.38
85 sound 1 33.40 32.40 32.90 32.40 40.45
86 sound 2 33.16 - - - -
87 NICAM 33.05 33.05 32.35 33.05 39.80
88 */
89 #define PHILIPS_SET_PAL_I 0x01 /* Bit 2 always zero !*/
90 #define PHILIPS_SET_PAL_BGDK 0x09
91 #define PHILIPS_SET_PAL_L2 0x0a
92 #define PHILIPS_SET_PAL_L 0x0b
93
94 /* system switching for Philips FI1216MF MK2
95 from datasheet "1996 Jul 09",
96 */
97 #define PHILIPS_MF_SET_BG 0x01 /* Bit 2 must be zero, Bit 3 is system output */
98 #define PHILIPS_MF_SET_PAL_L 0x03
99 #define PHILIPS_MF_SET_PAL_L2 0x02
100
101
102 /* ---------------------------------------------------------------------- */
103
104 struct tunertype
105 {
106 char *name;
107 unsigned char Vendor;
108 unsigned char Type;
109
110 unsigned short thresh1; /* band switch VHF_LO <=> VHF_HI */
111 unsigned short thresh2; /* band switch VHF_HI <=> UHF */
112 unsigned char VHF_L;
113 unsigned char VHF_H;
114 unsigned char UHF;
115 unsigned char config;
116 unsigned short IFPCoff; /* 622.4=16*38.90 MHz PAL, 732=16*45.75 NTSC */
117 };
118
119 /*
120 * The floats in the tuner struct are computed at compile time
121 * by gcc and cast back to integers. Thus we don't violate the
122 * "no float in kernel" rule.
123 */
124 static struct tunertype tuners[] = {
125 { "Temic PAL (4002 FH5)", TEMIC, PAL,
126 16*140.25,16*463.25,0x02,0x04,0x01,0x8e,623},
127 { "Philips PAL_I", Philips, PAL_I,
128 16*140.25,16*463.25,0xa0,0x90,0x30,0x8e,623},
129 { "Philips NTSC", Philips, NTSC,
130 16*157.25,16*451.25,0xA0,0x90,0x30,0x8e,732},
131 { "Philips SECAM", Philips, SECAM,
132 16*168.25,16*447.25,0xA7,0x97,0x37,0x8e,623},
133
134 { "NoTuner", NoTuner, NOTUNER,
135 0,0,0x00,0x00,0x00,0x00,0x00},
136 { "Philips PAL", Philips, PAL,
137 16*168.25,16*447.25,0xA0,0x90,0x30,0x8e,623},
138 { "Temic NTSC (4032 FY5)", TEMIC, NTSC,
139 16*157.25,16*463.25,0x02,0x04,0x01,0x8e,732},
140 { "Temic PAL_I (4062 FY5)", TEMIC, PAL_I,
141 16*170.00,16*450.00,0x02,0x04,0x01,0x8e,623},
142
143 { "Temic NTSC (4036 FY5)", TEMIC, NTSC,
144 16*157.25,16*463.25,0xa0,0x90,0x30,0x8e,732},
145 { "Alps HSBH1", TEMIC, NTSC,
146 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732},
147 { "Alps TSBE1",TEMIC,PAL,
148 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732},
149 { "Alps TSBB5", Alps, PAL_I, /* tested (UK UHF) with Modtec MM205 */
150 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,632},
151
152 { "Alps TSBE5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */
153 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,622},
154 { "Alps TSBC5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */
155 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,608},
156 { "Temic PAL_I (4006FH5)", TEMIC, PAL_I,
157 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
158 { "Alps TSCH6",Alps,NTSC,
159 16*137.25,16*385.25,0x14,0x12,0x11,0x8e,732},
160
161 { "Temic PAL_DK (4016 FY5)",TEMIC,PAL,
162 16*136.25,16*456.25,0xa0,0x90,0x30,0x8e,623},
163 { "Philips NTSC_M (MK2)",Philips,NTSC,
164 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732},
165 { "Temic PAL_I (4066 FY5)", TEMIC, PAL_I,
166 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
167 { "Temic PAL* auto (4006 FN5)", TEMIC, PAL,
168 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
169
170 { "Temic PAL (4009 FR5)", TEMIC, PAL,
171 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623},
172 { "Temic NTSC (4039 FR5)", TEMIC, NTSC,
173 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732},
174 { "Temic PAL/SECAM multi (4046 FM5)", TEMIC, PAL,
175 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623},
176 { "Philips PAL_DK", Philips, PAL,
177 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
178
179 { "Philips PAL/SECAM multi (FQ1216ME)", Philips, PAL,
180 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
181 { "LG PAL_I+FM (TAPC-I001D)", LGINNOTEK, PAL_I,
182 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
183 { "LG PAL_I (TAPC-I701D)", LGINNOTEK, PAL_I,
184 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
185 { "LG NTSC+FM (TPI8NSR01F)", LGINNOTEK, NTSC,
186 16*210.00,16*497.00,0xa0,0x90,0x30,0x8e,732},
187
188 { "LG PAL_BG+FM (TPI8PSB01D)", LGINNOTEK, PAL,
189 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
190 { "LG PAL_BG (TPI8PSB11D)", LGINNOTEK, PAL,
191 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
192 { "Temic PAL* auto + FM (4009 FN5)", TEMIC, PAL,
193 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623}
194 };
195 #define TUNERS (sizeof(tuners)/sizeof(struct tunertype))
196
197 /* ---------------------------------------------------------------------- */
198
199 static int tuner_getstatus(struct i2c_client *c)
200 {
201 unsigned char byte;
202
203 if (1 != i2c_master_recv(c,&byte,1))
204 return 0;
205 return byte;
206 }
207
208 #define TUNER_POR 0x80
209 #define TUNER_FL 0x40
210 #define TUNER_MODE 0x38
211 #define TUNER_AFC 0x07
212
213 #define TUNER_STEREO 0x10 /* radio mode */
214 #define TUNER_SIGNAL 0x07 /* radio mode */
215
216 static int tuner_signal(struct i2c_client *c)
217 {
218 return (tuner_getstatus(c) & TUNER_SIGNAL)<<13;
219 }
220
221 static int tuner_stereo(struct i2c_client *c)
222 {
223 return (tuner_getstatus (c) & TUNER_STEREO);
224 }
225
226
227 static int tuner_islocked (struct i2c_client *c)
228 {
229 return (tuner_getstatus (c) & TUNER_FL);
230 }
231
232 static int tuner_afcstatus (struct i2c_client *c)
233 {
234 return (tuner_getstatus (c) & TUNER_AFC) - 2;
235 }
236
237 #if 0 /* unused */
238 static int tuner_mode (struct i2c_client *c)
239 {
240 return (tuner_getstatus (c) & TUNER_MODE) >> 3;
241 }
242 #endif
243
244 // Set tuner frequency, freq in Units of 62.5kHz = 1/16MHz
245 static void set_tv_freq(struct i2c_client *c, int freq)
246 {
247 u8 config;
248 u16 div;
249 struct tunertype *tun;
250 struct tuner *t = c->data;
251 unsigned char buffer[4];
252 int rc;
253
254 if (freq < tv_range[0]*16 || freq > tv_range[1]*16) {
255 /* FIXME: better do that chip-specific, but
256 right now we don't have that in the config
257 struct and this way is still better than no
258 check at all */
259 printk("tuner: TV freq (%d.%02d) out of range (%d-%d)\n",
260 freq/16,freq%16*100/16,tv_range[0],tv_range[1]);
261 }
262
263 if (t->type == -1) {
264 printk("tuner: tuner type not set\n");
265 return;
266 }
267
268 tun=&tuners[t->type];
269 if (freq < tun->thresh1)
270 config = tun->VHF_L;
271 else if (freq < tun->thresh2)
272 config = tun->VHF_H;
273 else
274 config = tun->UHF;
275
276
277 /* tv norm specific stuff for multi-norm tuners */
278 switch (t->type) {
279 case TUNER_PHILIPS_SECAM:
280 /* 0x01 -> ??? no change ??? */
281 /* 0x02 -> PAL BDGHI / SECAM L */
282 /* 0x04 -> ??? PAL others / SECAM others ??? */
283 config &= ~0x02;
284 if (t->mode)
285 config |= 0x02;
286 break;
287
288 case TUNER_TEMIC_4046FM5:
289 config &= ~0x0f;
290 switch (pal[0]) {
291 case 'i':
292 case 'I':
293 config |= TEMIC_SET_PAL_I;
294 break;
295 case 'd':
296 case 'D':
297 config |= TEMIC_SET_PAL_DK;
298 break;
299 case 'l':
300 case 'L':
301 config |= TEMIC_SET_PAL_L;
302 break;
303 case 'b':
304 case 'B':
305 case 'g':
306 case 'G':
307 default:
308 config |= TEMIC_SET_PAL_BG;
309 break;
310 break;
311 }
312 case TUNER_PHILIPS_FQ1216ME:
313 config &= ~0x0f;
314 switch (pal[0]) {
315 case 'i':
316 case 'I':
317 config |= PHILIPS_SET_PAL_I;
318 break;
319 case 'l':
320 case 'L':
321 config |= PHILIPS_SET_PAL_L;
322 break;
323 case 'd':
324 case 'D':
325 case 'b':
326 case 'B':
327 case 'g':
328 case 'G':
329 config |= PHILIPS_SET_PAL_BGDK;
330 break;
331 break;
332 }
333 }
334
335
336 /*
337 * Philips FI1216MK2 remark from specification :
338 * for channel selection involving band switching, and to ensure
339 * smooth tuning to the desired channel without causing
340 * unnecessary charge pump action, it is recommended to consider
341 * the difference between wanted channel frequency and the
342 * current channel frequency. Unnecessary charge pump action
343 * will result in very low tuning voltage which may drive the
344 * oscillator to extreme conditions.
345 *
346 * Progfou: specification says to send config data before
347 * frequency in case (wanted frequency < current frequency).
348 */
349
350 div=freq + tun->IFPCoff;
351 if (t->type == TUNER_PHILIPS_SECAM && freq < t->freq) {
352 buffer[0] = tun->config;
353 buffer[1] = config;
354 buffer[2] = (div>>8) & 0x7f;
355 buffer[3] = div & 0xff;
356 } else {
357 buffer[0] = (div>>8) & 0x7f;
358 buffer[1] = div & 0xff;
359 buffer[2] = tun->config;
360 buffer[3] = config;
361 }
362
363 if (4 != (rc = i2c_master_send(c,buffer,4)))
364 printk("tuner: i2c i/o error: rc == %d (should be 4)\n",rc);
365
366 }
367
368 static void set_radio_freq(struct i2c_client *c, int freq)
369 {
370 u8 config;
371 u16 div;
372 struct tunertype *tun;
373 struct tuner *t = (struct tuner*)c->data;
374 unsigned char buffer[4];
375 int rc;
376
377 if (freq < radio_range[0]*16 || freq > radio_range[1]*16) {
378 printk("tuner: radio freq (%d.%02d) out of range (%d-%d)\n",
379 freq/16,freq%16*100/16,
380 radio_range[0],radio_range[1]);
381 return;
382 }
383 if (t->type == -1) {
384 printk("tuner: tuner type not set\n");
385 return;
386 }
387
388 tun=&tuners[t->type];
389 config = 0xa4 /* 0xa5 */; /* bit 0 is AFC (set) vs. RF-Signal (clear) */
390 div=freq + (int)(16*10.7);
391 div&=0x7fff;
392
393 buffer[0] = (div>>8) & 0x7f;
394 buffer[1] = div & 0xff;
395 buffer[2] = tun->config;
396 buffer[3] = config;
397 if (4 != (rc = i2c_master_send(c,buffer,4)))
398 printk("tuner: i2c i/o error: rc == %d (should be 4)\n",rc);
399
400 if (debug) {
401 current->state = TASK_INTERRUPTIBLE;
402 schedule_timeout(HZ/10);
403
404 if (tuner_islocked (c))
405 printk ("tuner: PLL locked\n");
406 else
407 printk ("tuner: PLL not locked\n");
408
409 if (config & 1) {
410 printk ("tuner: AFC: %d\n", tuner_afcstatus(c));
411 } else {
412 printk ("tuner: Signal: %d\n", tuner_signal(c));
413 }
414 }
415 }
416 /* ---------------------------------------------------------------------- */
417
418
419 static int tuner_attach(struct i2c_adapter *adap, int addr,
420 unsigned short flags, int kind)
421 {
422 struct tuner *t;
423 struct i2c_client *client;
424
425 if (this_adap > 0)
426 return -1;
427 this_adap++;
428
429 client_template.adapter = adap;
430 client_template.addr = addr;
431
432 printk("tuner: chip found @ 0x%x\n", addr<<1);
433
434 if (NULL == (client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL)))
435 return -ENOMEM;
436 memcpy(client,&client_template,sizeof(struct i2c_client));
437 client->data = t = kmalloc(sizeof(struct tuner),GFP_KERNEL);
438 if (NULL == t) {
439 kfree(client);
440 return -ENOMEM;
441 }
442 memset(t,0,sizeof(struct tuner));
443 if (type >= 0 && type < TUNERS) {
444 t->type = type;
445 strncpy(client->name, tuners[t->type].name, sizeof(client->name));
446 } else {
447 t->type = -1;
448 }
449 i2c_attach_client(client);
450 MOD_INC_USE_COUNT;
451
452 return 0;
453 }
454
455 static int tuner_probe(struct i2c_adapter *adap)
456 {
457 if (0 != addr) {
458 normal_i2c_range[0] = addr;
459 normal_i2c_range[1] = addr;
460 }
461 this_adap = 0;
462 if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848))
463 return i2c_probe(adap, &addr_data, tuner_attach);
464 return 0;
465 }
466
467 static int tuner_detach(struct i2c_client *client)
468 {
469 struct tuner *t = (struct tuner*)client->data;
470
471 i2c_detach_client(client);
472 kfree(t);
473 kfree(client);
474 MOD_DEC_USE_COUNT;
475 return 0;
476 }
477
478 static int
479 tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
480 {
481 struct tuner *t = (struct tuner*)client->data;
482 int *iarg = (int*)arg;
483 #if 0
484 __u16 *sarg = (__u16*)arg;
485 #endif
486
487 switch (cmd) {
488
489 /* --- configuration --- */
490 case TUNER_SET_TYPE:
491 if (t->type != -1)
492 return 0;
493 if (*iarg < 0 || *iarg >= TUNERS)
494 return 0;
495 t->type = *iarg;
496 dprintk("tuner: type set to %d (%s)\n",
497 t->type,tuners[t->type].name);
498 strncpy(client->name, tuners[t->type].name, sizeof(client->name));
499 break;
500 case AUDC_SET_RADIO:
501 t->radio = 1;
502 break;
503
504 /* --- v4l ioctls --- */
505 /* take care: bttv does userspace copying, we'll get a
506 kernel pointer here... */
507 case VIDIOCSCHAN:
508 {
509 struct video_channel *vc = arg;
510
511 t->radio = 0;
512 if (t->type == TUNER_PHILIPS_SECAM) {
513 t->mode = (vc->norm == VIDEO_MODE_SECAM) ? 1 : 0;
514 set_tv_freq(client,t->freq);
515 }
516 return 0;
517 }
518 case VIDIOCSFREQ:
519 {
520 unsigned long *v = arg;
521
522 if (t->radio) {
523 dprintk("tuner: radio freq set to %d.%02d\n",
524 (*iarg)/16,(*iarg)%16*100/16);
525 set_radio_freq(client,*v);
526 } else {
527 dprintk("tuner: tv freq set to %d.%02d\n",
528 (*iarg)/16,(*iarg)%16*100/16);
529 set_tv_freq(client,*v);
530 }
531 t->freq = *v;
532 return 0;
533 }
534 case VIDIOCGTUNER:
535 {
536 struct video_tuner *vt = arg;
537
538 if (t->radio)
539 vt->signal = tuner_signal(client);
540 return 0;
541 }
542 case VIDIOCGAUDIO:
543 {
544 struct video_audio *va = arg;
545 if (t->radio)
546 va->mode = (tuner_stereo(client) ? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO);
547 return 0;
548 }
549
550 #if 0
551 /* --- old, obsolete interface --- */
552 case TUNER_SET_TVFREQ:
553 dprintk("tuner: tv freq set to %d.%02d\n",
554 (*iarg)/16,(*iarg)%16*100/16);
555 set_tv_freq(client,*iarg);
556 t->radio = 0;
557 t->freq = *iarg;
558 break;
559
560 case TUNER_SET_RADIOFREQ:
561 dprintk("tuner: radio freq set to %d.%02d\n",
562 (*iarg)/16,(*iarg)%16*100/16);
563 set_radio_freq(client,*iarg);
564 t->radio = 1;
565 t->freq = *iarg;
566 break;
567 case TUNER_SET_MODE:
568 if (t->type != TUNER_PHILIPS_SECAM) {
569 dprintk("tuner: trying to change mode for other than TUNER_PHILIPS_SECAM\n");
570 } else {
571 int mode=(*sarg==VIDEO_MODE_SECAM)?1:0;
572 dprintk("tuner: mode set to %d\n", *sarg);
573 t->mode = mode;
574 set_tv_freq(client,t->freq);
575 }
576 break;
577 #endif
578 default:
579 /* nothing */
580 break;
581 }
582
583 return 0;
584 }
585
586 /* ----------------------------------------------------------------------- */
587
588 static struct i2c_driver driver = {
589 "i2c TV tuner driver",
590 I2C_DRIVERID_TUNER,
591 I2C_DF_NOTIFY,
592 tuner_probe,
593 tuner_detach,
594 tuner_command,
595 };
596
597 static struct i2c_client client_template =
598 {
599 "(unset)", /* name */
600 -1,
601 0,
602 0,
603 NULL,
604 &driver
605 };
606
607 EXPORT_NO_SYMBOLS;
608
609 int tuner_init_module(void)
610 {
611 i2c_add_driver(&driver);
612 return 0;
613 }
614
615 void tuner_cleanup_module(void)
616 {
617 i2c_del_driver(&driver);
618 }
619
620 module_init(tuner_init_module);
621 module_exit(tuner_cleanup_module);
622
623 /*
624 * Overrides for Emacs so that we follow Linus's tabbing style.
625 * ---------------------------------------------------------------------------
626 * Local variables:
627 * c-basic-offset: 8
628 * End:
629 */
630