Commit | Line | Data |
---|---|---|
1da177e4 | 1 | /* |
fd3113e8 | 2 | * $Id: tuner-simple.c,v 1.43 2005/07/28 18:41:21 mchehab Exp $ |
1da177e4 LT |
3 | * |
4 | * i2c tv tuner chip device driver | |
5 | * controls all those simple 4-control-bytes style tuners. | |
6 | */ | |
7 | #include <linux/delay.h> | |
8 | #include <linux/i2c.h> | |
9 | #include <linux/videodev.h> | |
10 | #include <media/tuner.h> | |
11 | ||
12 | /* ---------------------------------------------------------------------- */ | |
13 | ||
14 | /* tv standard selection for Temic 4046 FM5 | |
15 | this value takes the low bits of control byte 2 | |
16 | from datasheet Rev.01, Feb.00 | |
17 | standard BG I L L2 D | |
18 | picture IF 38.9 38.9 38.9 33.95 38.9 | |
19 | sound 1 33.4 32.9 32.4 40.45 32.4 | |
20 | sound 2 33.16 | |
21 | NICAM 33.05 32.348 33.05 33.05 | |
22 | */ | |
23 | #define TEMIC_SET_PAL_I 0x05 | |
24 | #define TEMIC_SET_PAL_DK 0x09 | |
25 | #define TEMIC_SET_PAL_L 0x0a // SECAM ? | |
26 | #define TEMIC_SET_PAL_L2 0x0b // change IF ! | |
27 | #define TEMIC_SET_PAL_BG 0x0c | |
28 | ||
29 | /* tv tuner system standard selection for Philips FQ1216ME | |
30 | this value takes the low bits of control byte 2 | |
31 | from datasheet "1999 Nov 16" (supersedes "1999 Mar 23") | |
32 | standard BG DK I L L` | |
33 | picture carrier 38.90 38.90 38.90 38.90 33.95 | |
34 | colour 34.47 34.47 34.47 34.47 38.38 | |
35 | sound 1 33.40 32.40 32.90 32.40 40.45 | |
36 | sound 2 33.16 - - - - | |
37 | NICAM 33.05 33.05 32.35 33.05 39.80 | |
38 | */ | |
39 | #define PHILIPS_SET_PAL_I 0x01 /* Bit 2 always zero !*/ | |
40 | #define PHILIPS_SET_PAL_BGDK 0x09 | |
41 | #define PHILIPS_SET_PAL_L2 0x0a | |
42 | #define PHILIPS_SET_PAL_L 0x0b | |
43 | ||
44 | /* system switching for Philips FI1216MF MK2 | |
45 | from datasheet "1996 Jul 09", | |
46 | standard BG L L' | |
47 | picture carrier 38.90 38.90 33.95 | |
48 | colour 34.47 34.37 38.38 | |
49 | sound 1 33.40 32.40 40.45 | |
50 | sound 2 33.16 - - | |
51 | NICAM 33.05 33.05 39.80 | |
52 | */ | |
53 | #define PHILIPS_MF_SET_BG 0x01 /* Bit 2 must be zero, Bit 3 is system output */ | |
54 | #define PHILIPS_MF_SET_PAL_L 0x03 // France | |
55 | #define PHILIPS_MF_SET_PAL_L2 0x02 // L' | |
56 | ||
f7ce3cc6 MCC |
57 | /* Control byte */ |
58 | ||
59 | #define TUNER_RATIO_MASK 0x06 /* Bit cb1:cb2 */ | |
60 | #define TUNER_RATIO_SELECT_50 0x00 | |
61 | #define TUNER_RATIO_SELECT_32 0x02 | |
62 | #define TUNER_RATIO_SELECT_166 0x04 | |
63 | #define TUNER_RATIO_SELECT_62 0x06 | |
64 | ||
65 | #define TUNER_CHARGE_PUMP 0x40 /* Bit cb6 */ | |
66 | ||
67 | /* Status byte */ | |
68 | ||
69 | #define TUNER_POR 0x80 | |
70 | #define TUNER_FL 0x40 | |
71 | #define TUNER_MODE 0x38 | |
72 | #define TUNER_AFC 0x07 | |
73 | #define TUNER_SIGNAL 0x07 | |
74 | #define TUNER_STEREO 0x10 | |
75 | ||
76 | #define TUNER_PLL_LOCKED 0x40 | |
77 | #define TUNER_STEREO_MK3 0x04 | |
1da177e4 LT |
78 | |
79 | /* ---------------------------------------------------------------------- */ | |
80 | ||
81 | struct tunertype | |
82 | { | |
83 | char *name; | |
84 | unsigned char Vendor; | |
85 | unsigned char Type; | |
86 | ||
87 | unsigned short thresh1; /* band switch VHF_LO <=> VHF_HI */ | |
88 | unsigned short thresh2; /* band switch VHF_HI <=> UHF */ | |
89 | unsigned char VHF_L; | |
90 | unsigned char VHF_H; | |
91 | unsigned char UHF; | |
92 | unsigned char config; | |
93 | unsigned short IFPCoff; /* 622.4=16*38.90 MHz PAL, | |
94 | 732 =16*45.75 NTSCi, | |
95 | 940 =16*58.75 NTSC-Japan | |
96 | 704 =16*44 ATSC */ | |
97 | }; | |
98 | ||
99 | /* | |
100 | * The floats in the tuner struct are computed at compile time | |
101 | * by gcc and cast back to integers. Thus we don't violate the | |
102 | * "no float in kernel" rule. | |
103 | */ | |
104 | static struct tunertype tuners[] = { | |
105 | { "Temic PAL (4002 FH5)", TEMIC, PAL, | |
106 | 16*140.25,16*463.25,0x02,0x04,0x01,0x8e,623}, | |
107 | { "Philips PAL_I (FI1246 and compatibles)", Philips, PAL_I, | |
108 | 16*140.25,16*463.25,0xa0,0x90,0x30,0x8e,623}, | |
109 | { "Philips NTSC (FI1236,FM1236 and compatibles)", Philips, NTSC, | |
110 | 16*157.25,16*451.25,0xA0,0x90,0x30,0x8e,732}, | |
111 | { "Philips (SECAM+PAL_BG) (FI1216MF, FM1216MF, FR1216MF)", Philips, SECAM, | |
112 | 16*168.25,16*447.25,0xA7,0x97,0x37,0x8e,623}, | |
113 | ||
114 | { "NoTuner", NoTuner, NOTUNER, | |
115 | 0,0,0x00,0x00,0x00,0x00,0x00}, | |
116 | { "Philips PAL_BG (FI1216 and compatibles)", Philips, PAL, | |
117 | 16*168.25,16*447.25,0xA0,0x90,0x30,0x8e,623}, | |
118 | { "Temic NTSC (4032 FY5)", TEMIC, NTSC, | |
119 | 16*157.25,16*463.25,0x02,0x04,0x01,0x8e,732}, | |
120 | { "Temic PAL_I (4062 FY5)", TEMIC, PAL_I, | |
121 | 16*170.00,16*450.00,0x02,0x04,0x01,0x8e,623}, | |
122 | ||
123 | { "Temic NTSC (4036 FY5)", TEMIC, NTSC, | |
124 | 16*157.25,16*463.25,0xa0,0x90,0x30,0x8e,732}, | |
125 | { "Alps HSBH1", TEMIC, NTSC, | |
126 | 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732}, | |
127 | { "Alps TSBE1",TEMIC,PAL, | |
128 | 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732}, | |
129 | { "Alps TSBB5", Alps, PAL_I, /* tested (UK UHF) with Modulartech MM205 */ | |
130 | 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,632}, | |
131 | ||
132 | { "Alps TSBE5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */ | |
133 | 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,622}, | |
134 | { "Alps TSBC5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */ | |
135 | 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,608}, | |
136 | { "Temic PAL_BG (4006FH5)", TEMIC, PAL, | |
137 | 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, | |
138 | { "Alps TSCH6",Alps,NTSC, | |
139 | 16*137.25,16*385.25,0x14,0x12,0x11,0x8e,732}, | |
140 | ||
141 | { "Temic PAL_DK (4016 FY5)",TEMIC,PAL, | |
142 | 16*168.25,16*456.25,0xa0,0x90,0x30,0x8e,623}, | |
143 | { "Philips NTSC_M (MK2)",Philips,NTSC, | |
144 | 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732}, | |
145 | { "Temic PAL_I (4066 FY5)", TEMIC, PAL_I, | |
146 | 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623}, | |
147 | { "Temic PAL* auto (4006 FN5)", TEMIC, PAL, | |
148 | 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623}, | |
149 | ||
150 | { "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)", TEMIC, PAL, | |
151 | 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623}, | |
152 | { "Temic NTSC (4039 FR5)", TEMIC, NTSC, | |
153 | 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732}, | |
154 | { "Temic PAL/SECAM multi (4046 FM5)", TEMIC, PAL, | |
155 | 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623}, | |
156 | { "Philips PAL_DK (FI1256 and compatibles)", Philips, PAL, | |
157 | 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, | |
158 | ||
159 | { "Philips PAL/SECAM multi (FQ1216ME)", Philips, PAL, | |
160 | 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, | |
161 | { "LG PAL_I+FM (TAPC-I001D)", LGINNOTEK, PAL_I, | |
162 | 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, | |
163 | { "LG PAL_I (TAPC-I701D)", LGINNOTEK, PAL_I, | |
164 | 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, | |
165 | { "LG NTSC+FM (TPI8NSR01F)", LGINNOTEK, NTSC, | |
166 | 16*210.00,16*497.00,0xa0,0x90,0x30,0x8e,732}, | |
167 | ||
168 | { "LG PAL_BG+FM (TPI8PSB01D)", LGINNOTEK, PAL, | |
169 | 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, | |
170 | { "LG PAL_BG (TPI8PSB11D)", LGINNOTEK, PAL, | |
171 | 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, | |
172 | { "Temic PAL* auto + FM (4009 FN5)", TEMIC, PAL, | |
173 | 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623}, | |
174 | { "SHARP NTSC_JP (2U5JF5540)", SHARP, NTSC, /* 940=16*58.75 NTSC@Japan */ | |
175 | 16*137.25,16*317.25,0x01,0x02,0x08,0x8e,940 }, | |
176 | ||
177 | { "Samsung PAL TCPM9091PD27", Samsung, PAL, /* from sourceforge v3tv */ | |
178 | 16*169,16*464,0xA0,0x90,0x30,0x8e,623}, | |
179 | { "MT20xx universal", Microtune,PAL|NTSC, | |
180 | /* see mt20xx.c for details */ }, | |
181 | { "Temic PAL_BG (4106 FH5)", TEMIC, PAL, | |
182 | 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623}, | |
183 | { "Temic PAL_DK/SECAM_L (4012 FY5)", TEMIC, PAL, | |
184 | 16*140.25, 16*463.25, 0x02,0x04,0x01,0x8e,623}, | |
185 | ||
186 | { "Temic NTSC (4136 FY5)", TEMIC, NTSC, | |
187 | 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732}, | |
188 | { "LG PAL (newer TAPC series)", LGINNOTEK, PAL, | |
189 | 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,623}, | |
190 | { "Philips PAL/SECAM multi (FM1216ME MK3)", Philips, PAL, | |
191 | 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,623 }, | |
192 | { "LG NTSC (newer TAPC series)", LGINNOTEK, NTSC, | |
193 | 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,732}, | |
194 | ||
195 | { "HITACHI V7-J180AT", HITACHI, NTSC, | |
196 | 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,940 }, | |
197 | { "Philips PAL_MK (FI1216 MK)", Philips, PAL, | |
198 | 16*140.25,16*463.25,0x01,0xc2,0xcf,0x8e,623}, | |
199 | { "Philips 1236D ATSC/NTSC daul in",Philips,ATSC, | |
200 | 16*157.25,16*454.00,0xa0,0x90,0x30,0x8e,732}, | |
201 | { "Philips NTSC MK3 (FM1236MK3 or FM1236/F)", Philips, NTSC, | |
202 | 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732}, | |
203 | ||
204 | { "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)", Philips, NTSC, | |
205 | 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732}, | |
206 | { "Microtune 4049 FM5",Microtune,PAL, | |
207 | 16*141.00,16*464.00,0xa0,0x90,0x30,0x8e,623}, | |
208 | { "Panasonic VP27s/ENGE4324D", Panasonic, NTSC, | |
209 | 16*160.00,16*454.00,0x01,0x02,0x08,0xce,940}, | |
210 | { "LG NTSC (TAPE series)", LGINNOTEK, NTSC, | |
211 | 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 }, | |
212 | ||
213 | { "Tenna TNF 8831 BGFF)", Philips, PAL, | |
214 | 16*161.25,16*463.25,0xa0,0x90,0x30,0x8e,623}, | |
215 | { "Microtune 4042 FI5 ATSC/NTSC dual in", Microtune, NTSC, | |
216 | 16*162.00,16*457.00,0xa2,0x94,0x31,0x8e,732}, | |
217 | { "TCL 2002N", TCL, NTSC, | |
218 | 16*172.00,16*448.00,0x01,0x02,0x08,0x8e,732}, | |
219 | { "Philips PAL/SECAM_D (FM 1256 I-H3)", Philips, PAL, | |
220 | 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,623 }, | |
221 | ||
222 | { "Thomson DDT 7610 (ATSC/NTSC)", THOMSON, ATSC, | |
223 | 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732}, | |
224 | { "Philips FQ1286", Philips, NTSC, | |
225 | 16*160.00,16*454.00,0x41,0x42,0x04,0x8e,940}, // UHF band untested | |
226 | { "tda8290+75", Philips,PAL|NTSC, | |
227 | /* see tda8290.c for details */ }, | |
228 | { "LG PAL (TAPE series)", LGINNOTEK, PAL, | |
229 | 16*170.00, 16*450.00, 0x01,0x02,0x08,0xce,623}, | |
230 | ||
586b0cab MCC |
231 | { "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL, |
232 | 16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 }, | |
233 | { "Philips FQ1236A MK4", Philips, NTSC, | |
234 | 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 }, | |
f7ce3cc6 | 235 | { "Ymec TVision TVF-8531MF/8831MF/8731MF", Philips, NTSC, |
391cd727 MCC |
236 | 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732}, |
237 | { "Ymec TVision TVF-5533MF", Philips, NTSC, | |
238 | 16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732}, | |
f7ce3cc6 | 239 | |
3c1d0185 MK |
240 | { "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC, |
241 | 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732}, | |
f7ce3cc6 | 242 | { "Tena TNF9533-D/IF/TNF9533-B/DF", Philips, PAL, |
586b0cab | 243 | 16*160.25,16*464.25,0x01,0x02,0x04,0x8e,623}, |
f7ce3cc6 MCC |
244 | { "Philips TEA5767HN FM Radio", Philips, RADIO, |
245 | /* see tea5767.c for details */}, | |
586b0cab MCC |
246 | { "Philips FMD1216ME MK3 Hybrid Tuner", Philips, PAL, |
247 | 16*160.00,16*442.00,0x51,0x52,0x54,0x86,623 }, | |
fd3113e8 MCC |
248 | |
249 | { "LG TDVS-H062F/TUA6034", LGINNOTEK, NTSC, | |
250 | 16*160.00,16*455.00,0x01,0x02,0x04,0x8e,732}, | |
251 | ||
252 | { "Ymec TVF66T5-B/DFF", Philips, PAL, | |
253 | 16*160.25,16*464.25,0x01,0x02,0x08,0x8e,623}, | |
1da177e4 | 254 | }; |
56fc08ca | 255 | |
1da177e4 LT |
256 | unsigned const int tuner_count = ARRAY_SIZE(tuners); |
257 | ||
258 | /* ---------------------------------------------------------------------- */ | |
259 | ||
260 | static int tuner_getstatus(struct i2c_client *c) | |
261 | { | |
262 | unsigned char byte; | |
263 | ||
264 | if (1 != i2c_master_recv(c,&byte,1)) | |
265 | return 0; | |
56fc08ca | 266 | |
1da177e4 LT |
267 | return byte; |
268 | } | |
269 | ||
1da177e4 LT |
270 | static int tuner_signal(struct i2c_client *c) |
271 | { | |
56fc08ca | 272 | return (tuner_getstatus(c) & TUNER_SIGNAL) << 13; |
1da177e4 LT |
273 | } |
274 | ||
275 | static int tuner_stereo(struct i2c_client *c) | |
276 | { | |
56fc08ca MCC |
277 | int stereo, status; |
278 | struct tuner *t = i2c_get_clientdata(c); | |
279 | ||
280 | status = tuner_getstatus (c); | |
281 | ||
282 | switch (t->type) { | |
283 | case TUNER_PHILIPS_FM1216ME_MK3: | |
284 | case TUNER_PHILIPS_FM1236_MK3: | |
285 | case TUNER_PHILIPS_FM1256_IH3: | |
286 | stereo = ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3); | |
287 | break; | |
288 | default: | |
289 | stereo = status & TUNER_STEREO; | |
290 | } | |
291 | ||
292 | return stereo; | |
1da177e4 LT |
293 | } |
294 | ||
1da177e4 LT |
295 | |
296 | /* ---------------------------------------------------------------------- */ | |
297 | ||
298 | static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) | |
299 | { | |
300 | struct tuner *t = i2c_get_clientdata(c); | |
301 | u8 config; | |
302 | u16 div; | |
303 | struct tunertype *tun; | |
304 | unsigned char buffer[4]; | |
305 | int rc; | |
306 | ||
307 | tun = &tuners[t->type]; | |
308 | if (freq < tun->thresh1) { | |
309 | config = tun->VHF_L; | |
310 | tuner_dbg("tv: VHF lowrange\n"); | |
311 | } else if (freq < tun->thresh2) { | |
312 | config = tun->VHF_H; | |
313 | tuner_dbg("tv: VHF high range\n"); | |
314 | } else { | |
315 | config = tun->UHF; | |
316 | tuner_dbg("tv: UHF range\n"); | |
317 | } | |
318 | ||
319 | ||
320 | /* tv norm specific stuff for multi-norm tuners */ | |
321 | switch (t->type) { | |
322 | case TUNER_PHILIPS_SECAM: // FI1216MF | |
323 | /* 0x01 -> ??? no change ??? */ | |
324 | /* 0x02 -> PAL BDGHI / SECAM L */ | |
325 | /* 0x04 -> ??? PAL others / SECAM others ??? */ | |
326 | config &= ~0x02; | |
327 | if (t->std & V4L2_STD_SECAM) | |
328 | config |= 0x02; | |
329 | break; | |
330 | ||
331 | case TUNER_TEMIC_4046FM5: | |
332 | config &= ~0x0f; | |
333 | ||
334 | if (t->std & V4L2_STD_PAL_BG) { | |
335 | config |= TEMIC_SET_PAL_BG; | |
336 | ||
337 | } else if (t->std & V4L2_STD_PAL_I) { | |
338 | config |= TEMIC_SET_PAL_I; | |
339 | ||
340 | } else if (t->std & V4L2_STD_PAL_DK) { | |
341 | config |= TEMIC_SET_PAL_DK; | |
342 | ||
343 | } else if (t->std & V4L2_STD_SECAM_L) { | |
344 | config |= TEMIC_SET_PAL_L; | |
345 | ||
346 | } | |
347 | break; | |
348 | ||
349 | case TUNER_PHILIPS_FQ1216ME: | |
350 | config &= ~0x0f; | |
351 | ||
352 | if (t->std & (V4L2_STD_PAL_BG|V4L2_STD_PAL_DK)) { | |
353 | config |= PHILIPS_SET_PAL_BGDK; | |
354 | ||
355 | } else if (t->std & V4L2_STD_PAL_I) { | |
356 | config |= PHILIPS_SET_PAL_I; | |
357 | ||
358 | } else if (t->std & V4L2_STD_SECAM_L) { | |
359 | config |= PHILIPS_SET_PAL_L; | |
360 | ||
361 | } | |
362 | break; | |
363 | ||
364 | case TUNER_PHILIPS_ATSC: | |
365 | /* 0x00 -> ATSC antenna input 1 */ | |
366 | /* 0x01 -> ATSC antenna input 2 */ | |
367 | /* 0x02 -> NTSC antenna input 1 */ | |
368 | /* 0x03 -> NTSC antenna input 2 */ | |
369 | config &= ~0x03; | |
370 | if (!(t->std & V4L2_STD_ATSC)) | |
371 | config |= 2; | |
372 | /* FIXME: input */ | |
373 | break; | |
374 | ||
375 | case TUNER_MICROTUNE_4042FI5: | |
376 | /* Set the charge pump for fast tuning */ | |
f7ce3cc6 | 377 | tun->config |= TUNER_CHARGE_PUMP; |
1da177e4 LT |
378 | break; |
379 | } | |
380 | ||
381 | /* | |
382 | * Philips FI1216MK2 remark from specification : | |
383 | * for channel selection involving band switching, and to ensure | |
384 | * smooth tuning to the desired channel without causing | |
385 | * unnecessary charge pump action, it is recommended to consider | |
386 | * the difference between wanted channel frequency and the | |
387 | * current channel frequency. Unnecessary charge pump action | |
388 | * will result in very low tuning voltage which may drive the | |
389 | * oscillator to extreme conditions. | |
390 | * | |
391 | * Progfou: specification says to send config data before | |
392 | * frequency in case (wanted frequency < current frequency). | |
393 | */ | |
394 | ||
395 | div=freq + tun->IFPCoff; | |
396 | if (t->type == TUNER_PHILIPS_SECAM && freq < t->freq) { | |
397 | buffer[0] = tun->config; | |
398 | buffer[1] = config; | |
399 | buffer[2] = (div>>8) & 0x7f; | |
400 | buffer[3] = div & 0xff; | |
401 | } else { | |
402 | buffer[0] = (div>>8) & 0x7f; | |
403 | buffer[1] = div & 0xff; | |
404 | buffer[2] = tun->config; | |
405 | buffer[3] = config; | |
406 | } | |
407 | tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n", | |
408 | buffer[0],buffer[1],buffer[2],buffer[3]); | |
409 | ||
410 | if (4 != (rc = i2c_master_send(c,buffer,4))) | |
411 | tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); | |
412 | ||
413 | if (t->type == TUNER_MICROTUNE_4042FI5) { | |
414 | // FIXME - this may also work for other tuners | |
415 | unsigned long timeout = jiffies + msecs_to_jiffies(1); | |
416 | u8 status_byte = 0; | |
417 | ||
418 | /* Wait until the PLL locks */ | |
419 | for (;;) { | |
420 | if (time_after(jiffies,timeout)) | |
421 | return; | |
422 | if (1 != (rc = i2c_master_recv(c,&status_byte,1))) { | |
423 | tuner_warn("i2c i/o read error: rc == %d (should be 1)\n",rc); | |
424 | break; | |
425 | } | |
f7ce3cc6 | 426 | if (status_byte & TUNER_PLL_LOCKED) |
1da177e4 LT |
427 | break; |
428 | udelay(10); | |
429 | } | |
430 | ||
431 | /* Set the charge pump for optimized phase noise figure */ | |
f7ce3cc6 | 432 | tun->config &= ~TUNER_CHARGE_PUMP; |
1da177e4 LT |
433 | buffer[0] = (div>>8) & 0x7f; |
434 | buffer[1] = div & 0xff; | |
435 | buffer[2] = tun->config; | |
436 | buffer[3] = config; | |
437 | tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n", | |
438 | buffer[0],buffer[1],buffer[2],buffer[3]); | |
439 | ||
440 | if (4 != (rc = i2c_master_send(c,buffer,4))) | |
441 | tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); | |
442 | } | |
443 | } | |
444 | ||
445 | static void default_set_radio_freq(struct i2c_client *c, unsigned int freq) | |
446 | { | |
447 | struct tunertype *tun; | |
448 | struct tuner *t = i2c_get_clientdata(c); | |
449 | unsigned char buffer[4]; | |
450 | unsigned div; | |
451 | int rc; | |
452 | ||
f7ce3cc6 MCC |
453 | tun = &tuners[t->type]; |
454 | div = (20 * freq / 16000) + (int)(20*10.7); /* IF 10.7 MHz */ | |
455 | buffer[2] = (tun->config & ~TUNER_RATIO_MASK) | TUNER_RATIO_SELECT_50; /* 50 kHz step */ | |
1da177e4 LT |
456 | |
457 | switch (t->type) { | |
56fc08ca | 458 | case TUNER_TENA_9533_DI: |
391cd727 | 459 | case TUNER_YMEC_TVF_5533MF: |
f7ce3cc6 MCC |
460 | tuner_dbg ("This tuner doesn't have FM. Most cards has a TEA5767 for FM\n"); |
461 | return; | |
1da177e4 LT |
462 | case TUNER_PHILIPS_FM1216ME_MK3: |
463 | case TUNER_PHILIPS_FM1236_MK3: | |
586b0cab | 464 | case TUNER_PHILIPS_FMD1216ME_MK3: |
1da177e4 LT |
465 | buffer[3] = 0x19; |
466 | break; | |
467 | case TUNER_PHILIPS_FM1256_IH3: | |
f7ce3cc6 | 468 | div = (20 * freq) / 16000 + (int)(33.3 * 20); /* IF 33.3 MHz */ |
1da177e4 LT |
469 | buffer[3] = 0x19; |
470 | break; | |
471 | case TUNER_LG_PAL_FM: | |
472 | buffer[3] = 0xa5; | |
473 | break; | |
474 | default: | |
475 | buffer[3] = 0xa4; | |
476 | break; | |
477 | } | |
478 | buffer[0] = (div>>8) & 0x7f; | |
479 | buffer[1] = div & 0xff; | |
480 | ||
481 | tuner_dbg("radio 0x%02x 0x%02x 0x%02x 0x%02x\n", | |
482 | buffer[0],buffer[1],buffer[2],buffer[3]); | |
483 | ||
484 | if (4 != (rc = i2c_master_send(c,buffer,4))) | |
485 | tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); | |
486 | } | |
487 | ||
488 | int default_tuner_init(struct i2c_client *c) | |
489 | { | |
490 | struct tuner *t = i2c_get_clientdata(c); | |
491 | ||
492 | tuner_info("type set to %d (%s)\n", | |
493 | t->type, tuners[t->type].name); | |
494 | strlcpy(c->name, tuners[t->type].name, sizeof(c->name)); | |
495 | ||
496 | t->tv_freq = default_set_tv_freq; | |
497 | t->radio_freq = default_set_radio_freq; | |
498 | t->has_signal = tuner_signal; | |
499 | t->is_stereo = tuner_stereo; | |
586b0cab | 500 | |
1da177e4 LT |
501 | return 0; |
502 | } | |
503 | ||
504 | /* | |
505 | * Overrides for Emacs so that we follow Linus's tabbing style. | |
506 | * --------------------------------------------------------------------------- | |
507 | * Local variables: | |
508 | * c-basic-offset: 8 | |
509 | * End: | |
510 | */ |