Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6
[linux-2.6] / drivers / media / video / tuner-simple.c
1 /*
2  *
3  * i2c tv tuner chip device driver
4  * controls all those simple 4-control-bytes style tuners.
5  */
6 #include <linux/delay.h>
7 #include <linux/i2c.h>
8 #include <linux/videodev.h>
9 #include <media/tuner.h>
10
11 static int offset = 0;
12 module_param(offset, int, 0666);
13 MODULE_PARM_DESC(offset,"Allows to specify an offset for tuner");
14
15 /* ---------------------------------------------------------------------- */
16
17 /* tv standard selection for Temic 4046 FM5
18    this value takes the low bits of control byte 2
19    from datasheet Rev.01, Feb.00
20      standard     BG      I       L       L2      D
21      picture IF   38.9    38.9    38.9    33.95   38.9
22      sound 1      33.4    32.9    32.4    40.45   32.4
23      sound 2      33.16
24      NICAM        33.05   32.348  33.05           33.05
25  */
26 #define TEMIC_SET_PAL_I         0x05
27 #define TEMIC_SET_PAL_DK        0x09
28 #define TEMIC_SET_PAL_L         0x0a // SECAM ?
29 #define TEMIC_SET_PAL_L2        0x0b // change IF !
30 #define TEMIC_SET_PAL_BG        0x0c
31
32 /* tv tuner system standard selection for Philips FQ1216ME
33    this value takes the low bits of control byte 2
34    from datasheet "1999 Nov 16" (supersedes "1999 Mar 23")
35      standard           BG      DK      I       L       L`
36      picture carrier    38.90   38.90   38.90   38.90   33.95
37      colour             34.47   34.47   34.47   34.47   38.38
38      sound 1            33.40   32.40   32.90   32.40   40.45
39      sound 2            33.16   -       -       -       -
40      NICAM              33.05   33.05   32.35   33.05   39.80
41  */
42 #define PHILIPS_SET_PAL_I       0x01 /* Bit 2 always zero !*/
43 #define PHILIPS_SET_PAL_BGDK    0x09
44 #define PHILIPS_SET_PAL_L2      0x0a
45 #define PHILIPS_SET_PAL_L       0x0b
46
47 /* system switching for Philips FI1216MF MK2
48    from datasheet "1996 Jul 09",
49     standard         BG     L      L'
50     picture carrier  38.90  38.90  33.95
51     colour           34.47  34.37  38.38
52     sound 1          33.40  32.40  40.45
53     sound 2          33.16  -      -
54     NICAM            33.05  33.05  39.80
55  */
56 #define PHILIPS_MF_SET_BG       0x01 /* Bit 2 must be zero, Bit 3 is system output */
57 #define PHILIPS_MF_SET_PAL_L    0x03 // France
58 #define PHILIPS_MF_SET_PAL_L2   0x02 // L'
59
60 /* Control byte */
61
62 #define TUNER_RATIO_MASK        0x06 /* Bit cb1:cb2 */
63 #define TUNER_RATIO_SELECT_50   0x00
64 #define TUNER_RATIO_SELECT_32   0x02
65 #define TUNER_RATIO_SELECT_166  0x04
66 #define TUNER_RATIO_SELECT_62   0x06
67
68 #define TUNER_CHARGE_PUMP       0x40  /* Bit cb6 */
69
70 /* Status byte */
71
72 #define TUNER_POR         0x80
73 #define TUNER_FL          0x40
74 #define TUNER_MODE        0x38
75 #define TUNER_AFC         0x07
76 #define TUNER_SIGNAL      0x07
77 #define TUNER_STEREO      0x10
78
79 #define TUNER_PLL_LOCKED   0x40
80 #define TUNER_STEREO_MK3   0x04
81
82 #define TUNER_MAX_RANGES   3
83
84 /* ---------------------------------------------------------------------- */
85
86 struct tunertype
87 {
88         char *name;
89
90         int count;
91         struct {
92                 unsigned short thresh;
93                 unsigned char cb;
94         } ranges[TUNER_MAX_RANGES];
95         unsigned char config;
96 };
97
98 /*
99  *      The floats in the tuner struct are computed at compile time
100  *      by gcc and cast back to integers. Thus we don't violate the
101  *      "no float in kernel" rule.
102  */
103 static struct tunertype tuners[] = {
104         /* 0-9 */
105         [TUNER_TEMIC_PAL] = { /* TEMIC PAL */
106                 .name   = "Temic PAL (4002 FH5)",
107                 .count  = 3,
108                 .ranges = {
109                         { 16 * 140.25 /*MHz*/, 0x02, },
110                         { 16 * 463.25 /*MHz*/, 0x04, },
111                         { 16 * 999.99        , 0x01, },
112                 },
113                 .config = 0x8e,
114         },
115         [TUNER_PHILIPS_PAL_I] = { /* Philips PAL_I */
116                 .name   = "Philips PAL_I (FI1246 and compatibles)",
117                 .count  = 3,
118                 .ranges = {
119                         { 16 * 140.25 /*MHz*/, 0xa0, },
120                         { 16 * 463.25 /*MHz*/, 0x90, },
121                         { 16 * 999.99        , 0x30, },
122                 },
123                 .config = 0x8e,
124         },
125         [TUNER_PHILIPS_NTSC] = { /* Philips NTSC */
126                 .name   = "Philips NTSC (FI1236,FM1236 and compatibles)",
127                 .count  = 3,
128                 .ranges = {
129                         { 16 * 157.25 /*MHz*/, 0xa0, },
130                         { 16 * 451.25 /*MHz*/, 0x90, },
131                         { 16 * 999.99        , 0x30, },
132                 },
133                 .config = 0x8e,
134         },
135         [TUNER_PHILIPS_SECAM] = { /* Philips SECAM */
136                 .name   = "Philips (SECAM+PAL_BG) (FI1216MF, FM1216MF, FR1216MF)",
137                 .count  = 3,
138                 .ranges = {
139                         { 16 * 168.25 /*MHz*/, 0xa7, },
140                         { 16 * 447.25 /*MHz*/, 0x97, },
141                         { 16 * 999.99        , 0x37, },
142                 },
143                 .config = 0x8e,
144         },
145         [TUNER_ABSENT] = { /* Tuner Absent */
146                 .name   = "NoTuner",
147                 .count  = 1,
148                 .ranges = {
149                         { 0, 0x00, },
150                 },
151                 .config = 0x00,
152         },
153         [TUNER_PHILIPS_PAL] = { /* Philips PAL */
154                 .name   = "Philips PAL_BG (FI1216 and compatibles)",
155                 .count  = 3,
156                 .ranges = {
157                         { 16 * 168.25 /*MHz*/, 0xa0, },
158                         { 16 * 447.25 /*MHz*/, 0x90, },
159                         { 16 * 999.99        , 0x30, },
160                 },
161                 .config = 0x8e,
162         },
163         [TUNER_TEMIC_NTSC] = { /* TEMIC NTSC */
164                 .name   = "Temic NTSC (4032 FY5)",
165                 .count  = 3,
166                 .ranges = {
167                         { 16 * 157.25 /*MHz*/, 0x02, },
168                         { 16 * 463.25 /*MHz*/, 0x04, },
169                         { 16 * 999.99        , 0x01, },
170                 },
171                 .config = 0x8e,
172         },
173         [TUNER_TEMIC_PAL_I] = { /* TEMIC PAL_I */
174                 .name   = "Temic PAL_I (4062 FY5)",
175                 .count  = 3,
176                 .ranges = {
177                         { 16 * 170.00 /*MHz*/, 0x02, },
178                         { 16 * 450.00 /*MHz*/, 0x04, },
179                         { 16 * 999.99        , 0x01, },
180                 },
181                 .config = 0x8e,
182         },
183         [TUNER_TEMIC_4036FY5_NTSC] = { /* TEMIC NTSC */
184                 .name   = "Temic NTSC (4036 FY5)",
185                 .count  = 3,
186                 .ranges = {
187                         { 16 * 157.25 /*MHz*/, 0xa0, },
188                         { 16 * 463.25 /*MHz*/, 0x90, },
189                         { 16 * 999.99        , 0x30, },
190                 },
191                 .config = 0x8e,
192         },
193         [TUNER_ALPS_TSBH1_NTSC] = { /* TEMIC NTSC */
194                 .name   = "Alps HSBH1",
195                 .count  = 3,
196                 .ranges = {
197                         { 16 * 137.25 /*MHz*/, 0x01, },
198                         { 16 * 385.25 /*MHz*/, 0x02, },
199                         { 16 * 999.99        , 0x08, },
200                 },
201                 .config = 0x8e,
202         },
203
204         /* 10-19 */
205         [TUNER_ALPS_TSBE1_PAL] = { /* TEMIC PAL */
206                 .name   = "Alps TSBE1",
207                 .count  = 3,
208                 .ranges = {
209                         { 16 * 137.25 /*MHz*/, 0x01, },
210                         { 16 * 385.25 /*MHz*/, 0x02, },
211                         { 16 * 999.99        , 0x08, },
212                 },
213                 .config = 0x8e,
214         },
215         [TUNER_ALPS_TSBB5_PAL_I] = { /* Alps PAL_I */
216                 .name   = "Alps TSBB5",
217                 .count  = 3,
218                 .ranges = {
219                         { 16 * 133.25 /*MHz*/, 0x01, },
220                         { 16 * 351.25 /*MHz*/, 0x02, },
221                         { 16 * 999.99        , 0x08, },
222                 },
223                 .config = 0x8e,
224         },
225         [TUNER_ALPS_TSBE5_PAL] = { /* Alps PAL */
226                 .name   = "Alps TSBE5",
227                 .count  = 3,
228                 .ranges = {
229                         { 16 * 133.25 /*MHz*/, 0x01, },
230                         { 16 * 351.25 /*MHz*/, 0x02, },
231                         { 16 * 999.99        , 0x08, },
232                 },
233                 .config = 0x8e,
234         },
235         [TUNER_ALPS_TSBC5_PAL] = { /* Alps PAL */
236                 .name   = "Alps TSBC5",
237                 .count  = 3,
238                 .ranges = {
239                         { 16 * 133.25 /*MHz*/, 0x01, },
240                         { 16 * 351.25 /*MHz*/, 0x02, },
241                         { 16 * 999.99        , 0x08, },
242                 },
243                 .config = 0x8e,
244         },
245         [TUNER_TEMIC_4006FH5_PAL] = { /* TEMIC PAL */
246                 .name   = "Temic PAL_BG (4006FH5)",
247                 .count  = 3,
248                 .ranges = {
249                         { 16 * 170.00 /*MHz*/, 0xa0, },
250                         { 16 * 450.00 /*MHz*/, 0x90, },
251                         { 16 * 999.99        , 0x30, },
252                 },
253                 .config = 0x8e,
254         },
255         [TUNER_ALPS_TSHC6_NTSC] = { /* Alps NTSC */
256                 .name   = "Alps TSCH6",
257                 .count  = 3,
258                 .ranges = {
259                         { 16 * 137.25 /*MHz*/, 0x14, },
260                         { 16 * 385.25 /*MHz*/, 0x12, },
261                         { 16 * 999.99        , 0x11, },
262                 },
263                 .config = 0x8e,
264         },
265         [TUNER_TEMIC_PAL_DK] = { /* TEMIC PAL */
266                 .name   = "Temic PAL_DK (4016 FY5)",
267                 .count  = 3,
268                 .ranges = {
269                         { 16 * 168.25 /*MHz*/, 0xa0, },
270                         { 16 * 456.25 /*MHz*/, 0x90, },
271                         { 16 * 999.99        , 0x30, },
272                 },
273                 .config = 0x8e,
274         },
275         [TUNER_PHILIPS_NTSC_M] = { /* Philips NTSC */
276                 .name   = "Philips NTSC_M (MK2)",
277                 .count  = 3,
278                 .ranges = {
279                         { 16 * 160.00 /*MHz*/, 0xa0, },
280                         { 16 * 454.00 /*MHz*/, 0x90, },
281                         { 16 * 999.99        , 0x30, },
282                 },
283                 .config = 0x8e,
284         },
285         [TUNER_TEMIC_4066FY5_PAL_I] = { /* TEMIC PAL_I */
286                 .name   = "Temic PAL_I (4066 FY5)",
287                 .count  = 3,
288                 .ranges = {
289                         { 16 * 169.00 /*MHz*/, 0xa0, },
290                         { 16 * 454.00 /*MHz*/, 0x90, },
291                         { 16 * 999.99        , 0x30, },
292                 },
293                 .config = 0x8e,
294         },
295         [TUNER_TEMIC_4006FN5_MULTI_PAL] = { /* TEMIC PAL */
296                 .name   = "Temic PAL* auto (4006 FN5)",
297                 .count  = 3,
298                 .ranges = {
299                         { 16 * 169.00 /*MHz*/, 0xa0, },
300                         { 16 * 454.00 /*MHz*/, 0x90, },
301                         { 16 * 999.99        , 0x30, },
302                 },
303                 .config = 0x8e,
304         },
305
306         /* 20-29 */
307         [TUNER_TEMIC_4009FR5_PAL] = { /* TEMIC PAL */
308                 .name   = "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)",
309                 .count  = 3,
310                 .ranges = {
311                         { 16 * 141.00 /*MHz*/, 0xa0, },
312                         { 16 * 464.00 /*MHz*/, 0x90, },
313                         { 16 * 999.99        , 0x30, },
314                 },
315                 .config = 0x8e,
316         },
317         [TUNER_TEMIC_4039FR5_NTSC] = { /* TEMIC NTSC */
318                 .name   = "Temic NTSC (4039 FR5)",
319                 .count  = 3,
320                 .ranges = {
321                         { 16 * 158.00 /*MHz*/, 0xa0, },
322                         { 16 * 453.00 /*MHz*/, 0x90, },
323                         { 16 * 999.99        , 0x30, },
324                 },
325                 .config = 0x8e,
326         },
327         [TUNER_TEMIC_4046FM5] = { /* TEMIC PAL */
328                 .name   = "Temic PAL/SECAM multi (4046 FM5)",
329                 .count  = 3,
330                 .ranges = {
331                         { 16 * 169.00 /*MHz*/, 0xa0, },
332                         { 16 * 454.00 /*MHz*/, 0x90, },
333                         { 16 * 999.99        , 0x30, },
334                 },
335                 .config = 0x8e,
336         },
337         [TUNER_PHILIPS_PAL_DK] = { /* Philips PAL */
338                 .name   = "Philips PAL_DK (FI1256 and compatibles)",
339                 .count  = 3,
340                 .ranges = {
341                         { 16 * 170.00 /*MHz*/, 0xa0, },
342                         { 16 * 450.00 /*MHz*/, 0x90, },
343                         { 16 * 999.99        , 0x30, },
344                 },
345                 .config = 0x8e,
346         },
347         [TUNER_PHILIPS_FQ1216ME] = { /* Philips PAL */
348                 .name   = "Philips PAL/SECAM multi (FQ1216ME)",
349                 .count  = 3,
350                 .ranges = {
351                         { 16 * 170.00 /*MHz*/, 0xa0, },
352                         { 16 * 450.00 /*MHz*/, 0x90, },
353                         { 16 * 999.99        , 0x30, },
354                 },
355                 .config = 0x8e,
356         },
357         [TUNER_LG_PAL_I_FM] = { /* LGINNOTEK PAL_I */
358                 .name   = "LG PAL_I+FM (TAPC-I001D)",
359                 .count  = 3,
360                 .ranges = {
361                         { 16 * 170.00 /*MHz*/, 0xa0, },
362                         { 16 * 450.00 /*MHz*/, 0x90, },
363                         { 16 * 999.99        , 0x30, },
364                 },
365                 .config = 0x8e,
366         },
367         [TUNER_LG_PAL_I] = { /* LGINNOTEK PAL_I */
368                 .name   = "LG PAL_I (TAPC-I701D)",
369                 .count  = 3,
370                 .ranges = {
371                         { 16 * 170.00 /*MHz*/, 0xa0, },
372                         { 16 * 450.00 /*MHz*/, 0x90, },
373                         { 16 * 999.99        , 0x30, },
374                 },
375                 .config = 0x8e,
376         },
377         [TUNER_LG_NTSC_FM] = { /* LGINNOTEK NTSC */
378                 .name   = "LG NTSC+FM (TPI8NSR01F)",
379                 .count  = 3,
380                 .ranges = {
381                         { 16 * 210.00 /*MHz*/, 0xa0, },
382                         { 16 * 497.00 /*MHz*/, 0x90, },
383                         { 16 * 999.99        , 0x30, },
384                 },
385                 .config = 0x8e,
386         },
387         [TUNER_LG_PAL_FM] = { /* LGINNOTEK PAL */
388                 .name   = "LG PAL_BG+FM (TPI8PSB01D)",
389                 .count  = 3,
390                 .ranges = {
391                         { 16 * 170.00 /*MHz*/, 0xa0, },
392                         { 16 * 450.00 /*MHz*/, 0x90, },
393                         { 16 * 999.99        , 0x30, },
394                 },
395                 .config = 0x8e,
396         },
397         [TUNER_LG_PAL] = { /* LGINNOTEK PAL */
398                 .name   = "LG PAL_BG (TPI8PSB11D)",
399                 .count  = 3,
400                 .ranges = {
401                         { 16 * 170.00 /*MHz*/, 0xa0, },
402                         { 16 * 450.00 /*MHz*/, 0x90, },
403                         { 16 * 999.99        , 0x30, },
404                 },
405                 .config = 0x8e,
406         },
407
408         /* 30-39 */
409         [TUNER_TEMIC_4009FN5_MULTI_PAL_FM] = { /* TEMIC PAL */
410                 .name   = "Temic PAL* auto + FM (4009 FN5)",
411                 .count  = 3,
412                 .ranges = {
413                         { 16 * 141.00 /*MHz*/, 0xa0, },
414                         { 16 * 464.00 /*MHz*/, 0x90, },
415                         { 16 * 999.99        , 0x30, },
416                 },
417                 .config = 0x8e,
418         },
419         [TUNER_SHARP_2U5JF5540_NTSC] = { /* SHARP NTSC */
420                 .name   = "SHARP NTSC_JP (2U5JF5540)",
421                 .count  = 3,
422                 .ranges = {
423                         { 16 * 137.25 /*MHz*/, 0x01, },
424                         { 16 * 317.25 /*MHz*/, 0x02, },
425                         { 16 * 999.99        , 0x08, },
426                 },
427                 .config = 0x8e,
428         },
429         [TUNER_Samsung_PAL_TCPM9091PD27] = { /* Samsung PAL */
430                 .name   = "Samsung PAL TCPM9091PD27",
431                 .count  = 3,
432                 .ranges = {
433                         { 16 * 169 /*MHz*/, 0xa0, },
434                         { 16 * 464 /*MHz*/, 0x90, },
435                         { 16 * 999.99     , 0x30, },
436                 },
437                 .config = 0x8e,
438         },
439         [TUNER_MT2032] = { /* Microtune PAL|NTSC */
440                 .name   = "MT20xx universal",
441           /* see mt20xx.c for details */ },
442         [TUNER_TEMIC_4106FH5] = { /* TEMIC PAL */
443                 .name   = "Temic PAL_BG (4106 FH5)",
444                 .count  = 3,
445                 .ranges = {
446                         { 16 * 141.00 /*MHz*/, 0xa0, },
447                         { 16 * 464.00 /*MHz*/, 0x90, },
448                         { 16 * 999.99        , 0x30, },
449                 },
450                 .config = 0x8e,
451         },
452         [TUNER_TEMIC_4012FY5] = { /* TEMIC PAL */
453                 .name   = "Temic PAL_DK/SECAM_L (4012 FY5)",
454                 .count  = 3,
455                 .ranges = {
456                         { 16 * 140.25 /*MHz*/, 0x02, },
457                         { 16 * 463.25 /*MHz*/, 0x04, },
458                         { 16 * 999.99        , 0x01, },
459                 },
460                 .config = 0x8e,
461         },
462         [TUNER_TEMIC_4136FY5] = { /* TEMIC NTSC */
463                 .name   = "Temic NTSC (4136 FY5)",
464                 .count  = 3,
465                 .ranges = {
466                         { 16 * 158.00 /*MHz*/, 0xa0, },
467                         { 16 * 453.00 /*MHz*/, 0x90, },
468                         { 16 * 999.99        , 0x30, },
469                 },
470                 .config = 0x8e,
471         },
472         [TUNER_LG_PAL_NEW_TAPC] = { /* LGINNOTEK PAL */
473                 .name   = "LG PAL (newer TAPC series)",
474                 .count  = 3,
475                 .ranges = {
476                         { 16 * 170.00 /*MHz*/, 0x01, },
477                         { 16 * 450.00 /*MHz*/, 0x02, },
478                         { 16 * 999.99        , 0x08, },
479                 },
480                 .config = 0x8e,
481         },
482         [TUNER_PHILIPS_FM1216ME_MK3] = { /* Philips PAL */
483                 .name   = "Philips PAL/SECAM multi (FM1216ME MK3)",
484                 .count  = 3,
485                 .ranges = {
486                         { 16 * 158.00 /*MHz*/, 0x01, },
487                         { 16 * 442.00 /*MHz*/, 0x02, },
488                         { 16 * 999.99        , 0x04, },
489                 },
490                 .config = 0x8e,
491         },
492         [TUNER_LG_NTSC_NEW_TAPC] = { /* LGINNOTEK NTSC */
493                 .name   = "LG NTSC (newer TAPC series)",
494                 .count  = 3,
495                 .ranges = {
496                         { 16 * 170.00 /*MHz*/, 0x01, },
497                         { 16 * 450.00 /*MHz*/, 0x02, },
498                         { 16 * 999.99        , 0x08, },
499                 },
500                 .config = 0x8e,
501         },
502
503         /* 40-49 */
504         [TUNER_HITACHI_NTSC] = { /* HITACHI NTSC */
505                 .name   = "HITACHI V7-J180AT",
506                 .count  = 3,
507                 .ranges = {
508                         { 16 * 170.00 /*MHz*/, 0x01, },
509                         { 16 * 450.00 /*MHz*/, 0x02, },
510                         { 16 * 999.99        , 0x08, },
511                 },
512                 .config = 0x8e,
513         },
514         [TUNER_PHILIPS_PAL_MK] = { /* Philips PAL */
515                 .name   = "Philips PAL_MK (FI1216 MK)",
516                 .count  = 3,
517                 .ranges = {
518                         { 16 * 140.25 /*MHz*/, 0x01, },
519                         { 16 * 463.25 /*MHz*/, 0xc2, },
520                         { 16 * 999.99        , 0xcf, },
521                 },
522                 .config = 0x8e,
523         },
524         [TUNER_PHILIPS_ATSC] = { /* Philips ATSC */
525                 .name   = "Philips 1236D ATSC/NTSC dual in",
526                 .count  = 3,
527                 .ranges = {
528                         { 16 * 157.25 /*MHz*/, 0xa0, },
529                         { 16 * 454.00 /*MHz*/, 0x90, },
530                         { 16 * 999.99        , 0x30, },
531                 },
532                 .config = 0x8e,
533         },
534         [TUNER_PHILIPS_FM1236_MK3] = { /* Philips NTSC */
535                 .name   = "Philips NTSC MK3 (FM1236MK3 or FM1236/F)",
536                 .count  = 3,
537                 .ranges = {
538                         { 16 * 160.00 /*MHz*/, 0x01, },
539                         { 16 * 442.00 /*MHz*/, 0x02, },
540                         { 16 * 999.99        , 0x04, },
541                 },
542                 .config = 0x8e,
543         },
544         [TUNER_PHILIPS_4IN1] = { /* Philips NTSC */
545                 .name   = "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)",
546                 .count  = 3,
547                 .ranges = {
548                         { 16 * 160.00 /*MHz*/, 0x01, },
549                         { 16 * 442.00 /*MHz*/, 0x02, },
550                         { 16 * 999.99        , 0x04, },
551                 },
552                 .config = 0x8e,
553         },
554         [TUNER_MICROTUNE_4049FM5] = { /* Microtune PAL */
555                 .name   = "Microtune 4049 FM5",
556                 .count  = 3,
557                 .ranges = {
558                         { 16 * 141.00 /*MHz*/, 0xa0, },
559                         { 16 * 464.00 /*MHz*/, 0x90, },
560                         { 16 * 999.99        , 0x30, },
561                 },
562                 .config = 0x8e,
563         },
564         [TUNER_PANASONIC_VP27] = { /* Panasonic NTSC */
565                 .name   = "Panasonic VP27s/ENGE4324D",
566                 .count  = 3,
567                 .ranges = {
568                         { 16 * 160.00 /*MHz*/, 0x01, },
569                         { 16 * 454.00 /*MHz*/, 0x02, },
570                         { 16 * 999.99        , 0x08, },
571                 },
572                 .config = 0xce,
573         },
574         [TUNER_LG_NTSC_TAPE] = { /* LGINNOTEK NTSC */
575                 .name   = "LG NTSC (TAPE series)",
576                 .count  = 3,
577                 .ranges = {
578                         { 16 * 160.00 /*MHz*/, 0x01, },
579                         { 16 * 442.00 /*MHz*/, 0x02, },
580                         { 16 * 999.99        , 0x04, },
581                 },
582                 .config = 0x8e,
583         },
584         [TUNER_TNF_8831BGFF] = { /* Philips PAL */
585                 .name   = "Tenna TNF 8831 BGFF)",
586                 .count  = 3,
587                 .ranges = {
588                         { 16 * 161.25 /*MHz*/, 0xa0, },
589                         { 16 * 463.25 /*MHz*/, 0x90, },
590                         { 16 * 999.99        , 0x30, },
591                 },
592                 .config = 0x8e,
593         },
594         [TUNER_MICROTUNE_4042FI5] = { /* Microtune NTSC */
595                 .name   = "Microtune 4042 FI5 ATSC/NTSC dual in",
596                 .count  = 3,
597                 .ranges = {
598                         { 16 * 162.00 /*MHz*/, 0xa2, },
599                         { 16 * 457.00 /*MHz*/, 0x94, },
600                         { 16 * 999.99        , 0x31, },
601                 },
602                 .config = 0x8e,
603         },
604
605         /* 50-59 */
606         [TUNER_TCL_2002N] = { /* TCL NTSC */
607                 .name   = "TCL 2002N",
608                 .count  = 3,
609                 .ranges = {
610                         { 16 * 172.00 /*MHz*/, 0x01, },
611                         { 16 * 448.00 /*MHz*/, 0x02, },
612                         { 16 * 999.99        , 0x08, },
613                 },
614                 .config = 0x8e,
615         },
616         [TUNER_PHILIPS_FM1256_IH3] = { /* Philips PAL */
617                 .name   = "Philips PAL/SECAM_D (FM 1256 I-H3)",
618                 .count  = 3,
619                 .ranges = {
620                         { 16 * 160.00 /*MHz*/, 0x01, },
621                         { 16 * 442.00 /*MHz*/, 0x02, },
622                         { 16 * 999.99        , 0x04, },
623                 },
624                 .config = 0x8e,
625         },
626         [TUNER_THOMSON_DTT7610] = { /* THOMSON ATSC */
627                 .name   = "Thomson DTT 7610 (ATSC/NTSC)",
628                 .count  = 3,
629                 .ranges = {
630                         { 16 * 157.25 /*MHz*/, 0x39, },
631                         { 16 * 454.00 /*MHz*/, 0x3a, },
632                         { 16 * 999.99        , 0x3c, },
633                 },
634                 .config = 0x8e,
635         },
636         [TUNER_PHILIPS_FQ1286] = { /* Philips NTSC */
637                 .name   = "Philips FQ1286",
638                 .count  = 3,
639                 .ranges = {
640                         { 16 * 160.00 /*MHz*/, 0x41, },
641                         { 16 * 454.00 /*MHz*/, 0x42, },
642                         { 16 * 999.99        , 0x04, },
643                 },
644                 .config = 0x8e,
645         },
646         [TUNER_PHILIPS_TDA8290] = { /* Philips PAL|NTSC */
647                 .name   = "tda8290+75",
648           /* see tda8290.c for details */ },
649         [TUNER_TCL_2002MB] = { /* TCL PAL */
650                 .name   = "TCL 2002MB",
651                 .count  = 3,
652                 .ranges = {
653                         { 16 * 170.00 /*MHz*/, 0x01, },
654                         { 16 * 450.00 /*MHz*/, 0x02, },
655                         { 16 * 999.99        , 0x08, },
656                 },
657                 .config = 0xce,
658         },
659         [TUNER_PHILIPS_FQ1216AME_MK4] = { /* Philips PAL */
660                 .name   = "Philips PAL/SECAM multi (FQ1216AME MK4)",
661                 .count  = 3,
662                 .ranges = {
663                         { 16 * 160.00 /*MHz*/, 0x01, },
664                         { 16 * 442.00 /*MHz*/, 0x02, },
665                         { 16 * 999.99        , 0x04, },
666                 },
667                 .config = 0xce,
668         },
669         [TUNER_PHILIPS_FQ1236A_MK4] = { /* Philips NTSC */
670                 .name   = "Philips FQ1236A MK4",
671                 .count  = 3,
672                 .ranges = {
673                         { 16 * 160.00 /*MHz*/, 0x01, },
674                         { 16 * 442.00 /*MHz*/, 0x02, },
675                         { 16 * 999.99        , 0x04, },
676                 },
677                 .config = 0x8e,
678         },
679         [TUNER_YMEC_TVF_8531MF] = { /* Philips NTSC */
680                 .name   = "Ymec TVision TVF-8531MF/8831MF/8731MF",
681                 .count  = 3,
682                 .ranges = {
683                         { 16 * 160.00 /*MHz*/, 0xa0, },
684                         { 16 * 454.00 /*MHz*/, 0x90, },
685                         { 16 * 999.99        , 0x30, },
686                 },
687                 .config = 0x8e,
688         },
689         [TUNER_YMEC_TVF_5533MF] = { /* Philips NTSC */
690                 .name   = "Ymec TVision TVF-5533MF",
691                 .count  = 3,
692                 .ranges = {
693                         { 16 * 160.00 /*MHz*/, 0x01, },
694                         { 16 * 454.00 /*MHz*/, 0x02, },
695                         { 16 * 999.99        , 0x04, },
696                 },
697                 .config = 0x8e,
698         },
699
700         /* 60-69 */
701         [TUNER_THOMSON_DTT761X] = { /* THOMSON ATSC */
702                 /* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */
703                 .name   = "Thomson DTT 761X (ATSC/NTSC)",
704                 .count  = 3,
705                 .ranges = {
706                         { 16 * 145.25 /*MHz*/, 0x39, },
707                         { 16 * 415.25 /*MHz*/, 0x3a, },
708                         { 16 * 999.99        , 0x3c, },
709                 },
710                 .config = 0x8e,
711         },
712         [TUNER_TENA_9533_DI] = { /* Philips PAL */
713                 .name   = "Tena TNF9533-D/IF/TNF9533-B/DF",
714                 .count  = 3,
715                 .ranges = {
716                         { 16 * 160.25 /*MHz*/, 0x01, },
717                         { 16 * 464.25 /*MHz*/, 0x02, },
718                         { 16 * 999.99        , 0x04, },
719                 },
720                 .config = 0x8e,
721         },
722         [TUNER_TEA5767] = { /* Philips RADIO */
723                 .name   = "Philips TEA5767HN FM Radio",
724           /* see tea5767.c for details */},
725         [TUNER_PHILIPS_FMD1216ME_MK3] = { /* Philips PAL */
726                 .name   = "Philips FMD1216ME MK3 Hybrid Tuner",
727                 .count  = 3,
728                 .ranges = {
729                         { 16 * 160.00 /*MHz*/, 0x51, },
730                         { 16 * 442.00 /*MHz*/, 0x52, },
731                         { 16 * 999.99        , 0x54, },
732                 },
733                 .config = 0x86,
734         },
735         [TUNER_LG_TDVS_H062F] = { /* LGINNOTEK ATSC */
736                 .name   = "LG TDVS-H062F/TUA6034",
737                 .count  = 3,
738                 .ranges = {
739                         { 16 * 160.00 /*MHz*/, 0x01 },
740                         { 16 * 455.00 /*MHz*/, 0x02 },
741                         { 16 * 999.99        , 0x04 },
742                 },
743                 .config = 0x8e,
744         },
745         [TUNER_YMEC_TVF66T5_B_DFF] = { /* Philips PAL */
746                 .name   = "Ymec TVF66T5-B/DFF",
747                 .count  = 3,
748                 .ranges = {
749                         { 16 * 160.25 /*MHz*/, 0x01, },
750                         { 16 * 464.25 /*MHz*/, 0x02, },
751                         { 16 * 999.99        , 0x08, },
752                 },
753                 .config = 0x8e,
754         },
755         [TUNER_LG_NTSC_TALN_MINI] = { /* LGINNOTEK NTSC */
756                 .name   = "LG NTSC (TALN mini series)",
757                 .count  = 3,
758                 .ranges = {
759                         { 16 * 137.25 /*MHz*/, 0x01, },
760                         { 16 * 373.25 /*MHz*/, 0x02, },
761                         { 16 * 999.99        , 0x08, },
762                 },
763                 .config = 0x8e,
764         },
765         [TUNER_PHILIPS_TD1316] = { /* Philips PAL */
766                 .name   = "Philips TD1316 Hybrid Tuner",
767                 .count  = 3,
768                 .ranges = {
769                         { 16 * 160.00 /*MHz*/, 0xa1, },
770                         { 16 * 442.00 /*MHz*/, 0xa2, },
771                         { 16 * 999.99        , 0xa4, },
772                 },
773                 .config = 0xc8,
774         },
775         [TUNER_PHILIPS_TUV1236D] = { /* Philips ATSC */
776                 .name   = "Philips TUV1236D ATSC/NTSC dual in",
777                 .count  = 3,
778                 .ranges = {
779                         { 16 * 157.25 /*MHz*/, 0x01, },
780                         { 16 * 454.00 /*MHz*/, 0x02, },
781                         { 16 * 999.99        , 0x04, },
782                 },
783                 .config = 0xce,
784         },
785         [TUNER_TNF_5335MF] = { /* Philips NTSC */
786                 .name   = "Tena TNF 5335 MF",
787                 .count  = 3,
788                 .ranges = {
789                         { 16 * 157.25 /*MHz*/, 0x01, },
790                         { 16 * 454.00 /*MHz*/, 0x02, },
791                         { 16 * 999.99        , 0x04, },
792                 },
793                 .config = 0x8e,
794         },
795 };
796
797 unsigned const int tuner_count = ARRAY_SIZE(tuners);
798
799 /* ---------------------------------------------------------------------- */
800
801 static int tuner_getstatus(struct i2c_client *c)
802 {
803         unsigned char byte;
804
805         if (1 != i2c_master_recv(c,&byte,1))
806                 return 0;
807
808         return byte;
809 }
810
811 static int tuner_signal(struct i2c_client *c)
812 {
813         return (tuner_getstatus(c) & TUNER_SIGNAL) << 13;
814 }
815
816 static int tuner_stereo(struct i2c_client *c)
817 {
818         int stereo, status;
819         struct tuner *t = i2c_get_clientdata(c);
820
821         status = tuner_getstatus (c);
822
823         switch (t->type) {
824                 case TUNER_PHILIPS_FM1216ME_MK3:
825                 case TUNER_PHILIPS_FM1236_MK3:
826                 case TUNER_PHILIPS_FM1256_IH3:
827                         stereo = ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3);
828                         break;
829                 default:
830                         stereo = status & TUNER_STEREO;
831         }
832
833         return stereo;
834 }
835
836
837 /* ---------------------------------------------------------------------- */
838
839 static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
840 {
841         struct tuner *t = i2c_get_clientdata(c);
842         u8 config, tuneraddr;
843         u16 div;
844         struct tunertype *tun;
845         unsigned char buffer[4];
846         int rc, IFPCoff, i;
847
848         tun = &tuners[t->type];
849         for (i = 0; i < tun->count; i++) {
850                 if (freq > tun->ranges[i].thresh)
851                         continue;
852                 break;
853         }
854         config = tun->ranges[i].cb;
855         /*  i == 0 -> VHF_LO  */
856         /*  i == 1 -> VHF_HI  */
857         /*  i == 2 -> UHF     */
858         tuner_dbg("tv: range %d\n",i);
859
860         /* tv norm specific stuff for multi-norm tuners */
861         switch (t->type) {
862         case TUNER_PHILIPS_SECAM: // FI1216MF
863                 /* 0x01 -> ??? no change ??? */
864                 /* 0x02 -> PAL BDGHI / SECAM L */
865                 /* 0x04 -> ??? PAL others / SECAM others ??? */
866                 config &= ~0x02;
867                 if (t->std & V4L2_STD_SECAM)
868                         config |= 0x02;
869                 break;
870
871         case TUNER_TEMIC_4046FM5:
872                 config &= ~0x0f;
873
874                 if (t->std & V4L2_STD_PAL_BG) {
875                         config |= TEMIC_SET_PAL_BG;
876
877                 } else if (t->std & V4L2_STD_PAL_I) {
878                         config |= TEMIC_SET_PAL_I;
879
880                 } else if (t->std & V4L2_STD_PAL_DK) {
881                         config |= TEMIC_SET_PAL_DK;
882
883                 } else if (t->std & V4L2_STD_SECAM_L) {
884                         config |= TEMIC_SET_PAL_L;
885
886                 }
887                 break;
888
889         case TUNER_PHILIPS_FQ1216ME:
890                 config &= ~0x0f;
891
892                 if (t->std & (V4L2_STD_PAL_BG|V4L2_STD_PAL_DK)) {
893                         config |= PHILIPS_SET_PAL_BGDK;
894
895                 } else if (t->std & V4L2_STD_PAL_I) {
896                         config |= PHILIPS_SET_PAL_I;
897
898                 } else if (t->std & V4L2_STD_SECAM_L) {
899                         config |= PHILIPS_SET_PAL_L;
900
901                 }
902                 break;
903
904         case TUNER_PHILIPS_ATSC:
905                 /* 0x00 -> ATSC antenna input 1 */
906                 /* 0x01 -> ATSC antenna input 2 */
907                 /* 0x02 -> NTSC antenna input 1 */
908                 /* 0x03 -> NTSC antenna input 2 */
909                 config &= ~0x03;
910                 if (!(t->std & V4L2_STD_ATSC))
911                         config |= 2;
912                 /* FIXME: input */
913                 break;
914
915         case TUNER_MICROTUNE_4042FI5:
916                 /* Set the charge pump for fast tuning */
917                 tun->config |= TUNER_CHARGE_PUMP;
918                 break;
919
920         case TUNER_PHILIPS_TUV1236D:
921                 /* 0x40 -> ATSC antenna input 1 */
922                 /* 0x48 -> ATSC antenna input 2 */
923                 /* 0x00 -> NTSC antenna input 1 */
924                 /* 0x08 -> NTSC antenna input 2 */
925                 buffer[0] = 0x14;
926                 buffer[1] = 0x00;
927                 buffer[2] = 0x17;
928                 buffer[3] = 0x00;
929                 config &= ~0x40;
930                 if (t->std & V4L2_STD_ATSC) {
931                         config |= 0x40;
932                         buffer[1] = 0x04;
933                 }
934                 /* set to the correct mode (analog or digital) */
935                 tuneraddr = c->addr;
936                 c->addr = 0x0a;
937                 if (2 != (rc = i2c_master_send(c,&buffer[0],2)))
938                         tuner_warn("i2c i/o error: rc == %d (should be 2)\n",rc);
939                 if (2 != (rc = i2c_master_send(c,&buffer[2],2)))
940                         tuner_warn("i2c i/o error: rc == %d (should be 2)\n",rc);
941                 c->addr = tuneraddr;
942                 /* FIXME: input */
943                 break;
944         }
945
946         /*
947          * Philips FI1216MK2 remark from specification :
948          * for channel selection involving band switching, and to ensure
949          * smooth tuning to the desired channel without causing
950          * unnecessary charge pump action, it is recommended to consider
951          * the difference between wanted channel frequency and the
952          * current channel frequency.  Unnecessary charge pump action
953          * will result in very low tuning voltage which may drive the
954          * oscillator to extreme conditions.
955          *
956          * Progfou: specification says to send config data before
957          * frequency in case (wanted frequency < current frequency).
958          */
959
960         /* IFPCoff = Video Intermediate Frequency - Vif:
961                 940  =16*58.75  NTSC/J (Japan)
962                 732  =16*45.75  M/N STD
963                 704  =16*44     ATSC (at DVB code)
964                 632  =16*39.50  I U.K.
965                 622.4=16*38.90  B/G D/K I, L STD
966                 592  =16*37.00  D China
967                 590  =16.36.875 B Australia
968                 543.2=16*33.95  L' STD
969                 171.2=16*10.70  FM Radio (at set_radio_freq)
970         */
971
972         if (t->std == V4L2_STD_NTSC_M_JP) {
973                 IFPCoff = 940;
974         } else if ((t->std & V4L2_STD_MN) &&
975                   !(t->std & ~V4L2_STD_MN)) {
976                 IFPCoff = 732;
977         } else if (t->std == V4L2_STD_SECAM_LC) {
978                 IFPCoff = 543;
979         } else {
980                 IFPCoff = 623;
981         }
982
983         div=freq + IFPCoff + offset;
984
985         tuner_dbg("Freq= %d.%02d MHz, V_IF=%d.%02d MHz, Offset=%d.%02d MHz, div=%0d\n",
986                                         freq / 16, freq % 16 * 100 / 16,
987                                         IFPCoff / 16, IFPCoff % 16 * 100 / 16,
988                                         offset / 16, offset % 16 * 100 / 16,
989                                         div);
990
991         if (t->type == TUNER_PHILIPS_SECAM && freq < t->freq) {
992                 buffer[0] = tun->config;
993                 buffer[1] = config;
994                 buffer[2] = (div>>8) & 0x7f;
995                 buffer[3] = div      & 0xff;
996         } else {
997                 buffer[0] = (div>>8) & 0x7f;
998                 buffer[1] = div      & 0xff;
999                 buffer[2] = tun->config;
1000                 buffer[3] = config;
1001         }
1002         tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
1003                   buffer[0],buffer[1],buffer[2],buffer[3]);
1004
1005         if (4 != (rc = i2c_master_send(c,buffer,4)))
1006                 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc);
1007
1008         if (t->type == TUNER_MICROTUNE_4042FI5) {
1009                 // FIXME - this may also work for other tuners
1010                 unsigned long timeout = jiffies + msecs_to_jiffies(1);
1011                 u8 status_byte = 0;
1012
1013                 /* Wait until the PLL locks */
1014                 for (;;) {
1015                         if (time_after(jiffies,timeout))
1016                                 return;
1017                         if (1 != (rc = i2c_master_recv(c,&status_byte,1))) {
1018                                 tuner_warn("i2c i/o read error: rc == %d (should be 1)\n",rc);
1019                                 break;
1020                         }
1021                         if (status_byte & TUNER_PLL_LOCKED)
1022                                 break;
1023                         udelay(10);
1024                 }
1025
1026                 /* Set the charge pump for optimized phase noise figure */
1027                 tun->config &= ~TUNER_CHARGE_PUMP;
1028                 buffer[0] = (div>>8) & 0x7f;
1029                 buffer[1] = div      & 0xff;
1030                 buffer[2] = tun->config;
1031                 buffer[3] = config;
1032                 tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
1033                        buffer[0],buffer[1],buffer[2],buffer[3]);
1034
1035                 if (4 != (rc = i2c_master_send(c,buffer,4)))
1036                         tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc);
1037         }
1038 }
1039
1040 static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
1041 {
1042         struct tunertype *tun;
1043         struct tuner *t = i2c_get_clientdata(c);
1044         unsigned char buffer[4];
1045         unsigned div;
1046         int rc;
1047
1048         tun = &tuners[t->type];
1049         div = (20 * freq / 16000) + (int)(20*10.7); /* IF 10.7 MHz */
1050         buffer[2] = (tun->config & ~TUNER_RATIO_MASK) | TUNER_RATIO_SELECT_50; /* 50 kHz step */
1051
1052         switch (t->type) {
1053         case TUNER_TENA_9533_DI:
1054         case TUNER_YMEC_TVF_5533MF:
1055                 tuner_dbg ("This tuner doesn't have FM. Most cards has a TEA5767 for FM\n");
1056                 return;
1057         case TUNER_PHILIPS_FM1216ME_MK3:
1058         case TUNER_PHILIPS_FM1236_MK3:
1059         case TUNER_PHILIPS_FMD1216ME_MK3:
1060                 buffer[3] = 0x19;
1061                 break;
1062         case TUNER_PHILIPS_FM1256_IH3:
1063                 div = (20 * freq) / 16000 + (int)(33.3 * 20);  /* IF 33.3 MHz */
1064                 buffer[3] = 0x19;
1065                 break;
1066         case TUNER_LG_PAL_FM:
1067                 buffer[3] = 0xa5;
1068                 break;
1069         case TUNER_MICROTUNE_4049FM5:
1070                 div = (20 * freq) / 16000 + (int)(33.3 * 20); /* IF 33.3 MHz */
1071                 buffer[3] = 0xa4;
1072                 break;
1073         default:
1074                 buffer[3] = 0xa4;
1075                 break;
1076         }
1077         buffer[0] = (div>>8) & 0x7f;
1078         buffer[1] = div      & 0xff;
1079
1080         tuner_dbg("radio 0x%02x 0x%02x 0x%02x 0x%02x\n",
1081                buffer[0],buffer[1],buffer[2],buffer[3]);
1082
1083         if (4 != (rc = i2c_master_send(c,buffer,4)))
1084                 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc);
1085 }
1086
1087 int default_tuner_init(struct i2c_client *c)
1088 {
1089         struct tuner *t = i2c_get_clientdata(c);
1090
1091         tuner_info("type set to %d (%s)\n",
1092                    t->type, tuners[t->type].name);
1093         strlcpy(c->name, tuners[t->type].name, sizeof(c->name));
1094
1095         t->tv_freq    = default_set_tv_freq;
1096         t->radio_freq = default_set_radio_freq;
1097         t->has_signal = tuner_signal;
1098         t->is_stereo  = tuner_stereo;
1099         t->standby = NULL;
1100
1101         return 0;
1102 }
1103
1104 /*
1105  * Overrides for Emacs so that we follow Linus's tabbing style.
1106  * ---------------------------------------------------------------------------
1107  * Local variables:
1108  * c-basic-offset: 8
1109  * End:
1110  */