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