diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/media/video/tuner-simple.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/media/video/tuner-simple.c')
-rw-r--r-- | drivers/media/video/tuner-simple.c | 474 |
1 files changed, 474 insertions, 0 deletions
diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c new file mode 100644 index 000000000000..48c6ceff1dc2 --- /dev/null +++ b/drivers/media/video/tuner-simple.c | |||
@@ -0,0 +1,474 @@ | |||
1 | /* | ||
2 | * $Id: tuner-simple.c,v 1.10 2005/03/08 08:38:00 kraxel Exp $ | ||
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 | |||
57 | |||
58 | /* ---------------------------------------------------------------------- */ | ||
59 | |||
60 | struct tunertype | ||
61 | { | ||
62 | char *name; | ||
63 | unsigned char Vendor; | ||
64 | unsigned char Type; | ||
65 | |||
66 | unsigned short thresh1; /* band switch VHF_LO <=> VHF_HI */ | ||
67 | unsigned short thresh2; /* band switch VHF_HI <=> UHF */ | ||
68 | unsigned char VHF_L; | ||
69 | unsigned char VHF_H; | ||
70 | unsigned char UHF; | ||
71 | unsigned char config; | ||
72 | unsigned short IFPCoff; /* 622.4=16*38.90 MHz PAL, | ||
73 | 732 =16*45.75 NTSCi, | ||
74 | 940 =16*58.75 NTSC-Japan | ||
75 | 704 =16*44 ATSC */ | ||
76 | }; | ||
77 | |||
78 | /* | ||
79 | * The floats in the tuner struct are computed at compile time | ||
80 | * by gcc and cast back to integers. Thus we don't violate the | ||
81 | * "no float in kernel" rule. | ||
82 | */ | ||
83 | static struct tunertype tuners[] = { | ||
84 | { "Temic PAL (4002 FH5)", TEMIC, PAL, | ||
85 | 16*140.25,16*463.25,0x02,0x04,0x01,0x8e,623}, | ||
86 | { "Philips PAL_I (FI1246 and compatibles)", Philips, PAL_I, | ||
87 | 16*140.25,16*463.25,0xa0,0x90,0x30,0x8e,623}, | ||
88 | { "Philips NTSC (FI1236,FM1236 and compatibles)", Philips, NTSC, | ||
89 | 16*157.25,16*451.25,0xA0,0x90,0x30,0x8e,732}, | ||
90 | { "Philips (SECAM+PAL_BG) (FI1216MF, FM1216MF, FR1216MF)", Philips, SECAM, | ||
91 | 16*168.25,16*447.25,0xA7,0x97,0x37,0x8e,623}, | ||
92 | |||
93 | { "NoTuner", NoTuner, NOTUNER, | ||
94 | 0,0,0x00,0x00,0x00,0x00,0x00}, | ||
95 | { "Philips PAL_BG (FI1216 and compatibles)", Philips, PAL, | ||
96 | 16*168.25,16*447.25,0xA0,0x90,0x30,0x8e,623}, | ||
97 | { "Temic NTSC (4032 FY5)", TEMIC, NTSC, | ||
98 | 16*157.25,16*463.25,0x02,0x04,0x01,0x8e,732}, | ||
99 | { "Temic PAL_I (4062 FY5)", TEMIC, PAL_I, | ||
100 | 16*170.00,16*450.00,0x02,0x04,0x01,0x8e,623}, | ||
101 | |||
102 | { "Temic NTSC (4036 FY5)", TEMIC, NTSC, | ||
103 | 16*157.25,16*463.25,0xa0,0x90,0x30,0x8e,732}, | ||
104 | { "Alps HSBH1", TEMIC, NTSC, | ||
105 | 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732}, | ||
106 | { "Alps TSBE1",TEMIC,PAL, | ||
107 | 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732}, | ||
108 | { "Alps TSBB5", Alps, PAL_I, /* tested (UK UHF) with Modulartech MM205 */ | ||
109 | 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,632}, | ||
110 | |||
111 | { "Alps TSBE5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */ | ||
112 | 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,622}, | ||
113 | { "Alps TSBC5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */ | ||
114 | 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,608}, | ||
115 | { "Temic PAL_BG (4006FH5)", TEMIC, PAL, | ||
116 | 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, | ||
117 | { "Alps TSCH6",Alps,NTSC, | ||
118 | 16*137.25,16*385.25,0x14,0x12,0x11,0x8e,732}, | ||
119 | |||
120 | { "Temic PAL_DK (4016 FY5)",TEMIC,PAL, | ||
121 | 16*168.25,16*456.25,0xa0,0x90,0x30,0x8e,623}, | ||
122 | { "Philips NTSC_M (MK2)",Philips,NTSC, | ||
123 | 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732}, | ||
124 | { "Temic PAL_I (4066 FY5)", TEMIC, PAL_I, | ||
125 | 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623}, | ||
126 | { "Temic PAL* auto (4006 FN5)", TEMIC, PAL, | ||
127 | 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623}, | ||
128 | |||
129 | { "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)", TEMIC, PAL, | ||
130 | 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623}, | ||
131 | { "Temic NTSC (4039 FR5)", TEMIC, NTSC, | ||
132 | 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732}, | ||
133 | { "Temic PAL/SECAM multi (4046 FM5)", TEMIC, PAL, | ||
134 | 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623}, | ||
135 | { "Philips PAL_DK (FI1256 and compatibles)", Philips, PAL, | ||
136 | 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, | ||
137 | |||
138 | { "Philips PAL/SECAM multi (FQ1216ME)", Philips, PAL, | ||
139 | 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, | ||
140 | { "LG PAL_I+FM (TAPC-I001D)", LGINNOTEK, PAL_I, | ||
141 | 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, | ||
142 | { "LG PAL_I (TAPC-I701D)", LGINNOTEK, PAL_I, | ||
143 | 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, | ||
144 | { "LG NTSC+FM (TPI8NSR01F)", LGINNOTEK, NTSC, | ||
145 | 16*210.00,16*497.00,0xa0,0x90,0x30,0x8e,732}, | ||
146 | |||
147 | { "LG PAL_BG+FM (TPI8PSB01D)", LGINNOTEK, PAL, | ||
148 | 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, | ||
149 | { "LG PAL_BG (TPI8PSB11D)", LGINNOTEK, PAL, | ||
150 | 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, | ||
151 | { "Temic PAL* auto + FM (4009 FN5)", TEMIC, PAL, | ||
152 | 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623}, | ||
153 | { "SHARP NTSC_JP (2U5JF5540)", SHARP, NTSC, /* 940=16*58.75 NTSC@Japan */ | ||
154 | 16*137.25,16*317.25,0x01,0x02,0x08,0x8e,940 }, | ||
155 | |||
156 | { "Samsung PAL TCPM9091PD27", Samsung, PAL, /* from sourceforge v3tv */ | ||
157 | 16*169,16*464,0xA0,0x90,0x30,0x8e,623}, | ||
158 | { "MT20xx universal", Microtune,PAL|NTSC, | ||
159 | /* see mt20xx.c for details */ }, | ||
160 | { "Temic PAL_BG (4106 FH5)", TEMIC, PAL, | ||
161 | 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623}, | ||
162 | { "Temic PAL_DK/SECAM_L (4012 FY5)", TEMIC, PAL, | ||
163 | 16*140.25, 16*463.25, 0x02,0x04,0x01,0x8e,623}, | ||
164 | |||
165 | { "Temic NTSC (4136 FY5)", TEMIC, NTSC, | ||
166 | 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732}, | ||
167 | { "LG PAL (newer TAPC series)", LGINNOTEK, PAL, | ||
168 | 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,623}, | ||
169 | { "Philips PAL/SECAM multi (FM1216ME MK3)", Philips, PAL, | ||
170 | 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,623 }, | ||
171 | { "LG NTSC (newer TAPC series)", LGINNOTEK, NTSC, | ||
172 | 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,732}, | ||
173 | |||
174 | { "HITACHI V7-J180AT", HITACHI, NTSC, | ||
175 | 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,940 }, | ||
176 | { "Philips PAL_MK (FI1216 MK)", Philips, PAL, | ||
177 | 16*140.25,16*463.25,0x01,0xc2,0xcf,0x8e,623}, | ||
178 | { "Philips 1236D ATSC/NTSC daul in",Philips,ATSC, | ||
179 | 16*157.25,16*454.00,0xa0,0x90,0x30,0x8e,732}, | ||
180 | { "Philips NTSC MK3 (FM1236MK3 or FM1236/F)", Philips, NTSC, | ||
181 | 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732}, | ||
182 | |||
183 | { "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)", Philips, NTSC, | ||
184 | 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732}, | ||
185 | { "Microtune 4049 FM5",Microtune,PAL, | ||
186 | 16*141.00,16*464.00,0xa0,0x90,0x30,0x8e,623}, | ||
187 | { "Panasonic VP27s/ENGE4324D", Panasonic, NTSC, | ||
188 | 16*160.00,16*454.00,0x01,0x02,0x08,0xce,940}, | ||
189 | { "LG NTSC (TAPE series)", LGINNOTEK, NTSC, | ||
190 | 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 }, | ||
191 | |||
192 | { "Tenna TNF 8831 BGFF)", Philips, PAL, | ||
193 | 16*161.25,16*463.25,0xa0,0x90,0x30,0x8e,623}, | ||
194 | { "Microtune 4042 FI5 ATSC/NTSC dual in", Microtune, NTSC, | ||
195 | 16*162.00,16*457.00,0xa2,0x94,0x31,0x8e,732}, | ||
196 | { "TCL 2002N", TCL, NTSC, | ||
197 | 16*172.00,16*448.00,0x01,0x02,0x08,0x8e,732}, | ||
198 | { "Philips PAL/SECAM_D (FM 1256 I-H3)", Philips, PAL, | ||
199 | 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,623 }, | ||
200 | |||
201 | { "Thomson DDT 7610 (ATSC/NTSC)", THOMSON, ATSC, | ||
202 | 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732}, | ||
203 | { "Philips FQ1286", Philips, NTSC, | ||
204 | 16*160.00,16*454.00,0x41,0x42,0x04,0x8e,940}, // UHF band untested | ||
205 | { "tda8290+75", Philips,PAL|NTSC, | ||
206 | /* see tda8290.c for details */ }, | ||
207 | { "LG PAL (TAPE series)", LGINNOTEK, PAL, | ||
208 | 16*170.00, 16*450.00, 0x01,0x02,0x08,0xce,623}, | ||
209 | |||
210 | { "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL, | ||
211 | 16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 }, | ||
212 | { "Philips FQ1236A MK4", Philips, NTSC, | ||
213 | 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 }, | ||
214 | |||
215 | }; | ||
216 | unsigned const int tuner_count = ARRAY_SIZE(tuners); | ||
217 | |||
218 | /* ---------------------------------------------------------------------- */ | ||
219 | |||
220 | static int tuner_getstatus(struct i2c_client *c) | ||
221 | { | ||
222 | unsigned char byte; | ||
223 | |||
224 | if (1 != i2c_master_recv(c,&byte,1)) | ||
225 | return 0; | ||
226 | return byte; | ||
227 | } | ||
228 | |||
229 | #define TUNER_POR 0x80 | ||
230 | #define TUNER_FL 0x40 | ||
231 | #define TUNER_MODE 0x38 | ||
232 | #define TUNER_AFC 0x07 | ||
233 | |||
234 | #define TUNER_STEREO 0x10 /* radio mode */ | ||
235 | #define TUNER_SIGNAL 0x07 /* radio mode */ | ||
236 | |||
237 | static int tuner_signal(struct i2c_client *c) | ||
238 | { | ||
239 | return (tuner_getstatus(c) & TUNER_SIGNAL)<<13; | ||
240 | } | ||
241 | |||
242 | static int tuner_stereo(struct i2c_client *c) | ||
243 | { | ||
244 | return (tuner_getstatus (c) & TUNER_STEREO); | ||
245 | } | ||
246 | |||
247 | #if 0 /* unused */ | ||
248 | static int tuner_islocked (struct i2c_client *c) | ||
249 | { | ||
250 | return (tuner_getstatus (c) & TUNER_FL); | ||
251 | } | ||
252 | |||
253 | static int tuner_afcstatus (struct i2c_client *c) | ||
254 | { | ||
255 | return (tuner_getstatus (c) & TUNER_AFC) - 2; | ||
256 | } | ||
257 | |||
258 | static int tuner_mode (struct i2c_client *c) | ||
259 | { | ||
260 | return (tuner_getstatus (c) & TUNER_MODE) >> 3; | ||
261 | } | ||
262 | #endif | ||
263 | |||
264 | /* ---------------------------------------------------------------------- */ | ||
265 | |||
266 | static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) | ||
267 | { | ||
268 | struct tuner *t = i2c_get_clientdata(c); | ||
269 | u8 config; | ||
270 | u16 div; | ||
271 | struct tunertype *tun; | ||
272 | unsigned char buffer[4]; | ||
273 | int rc; | ||
274 | |||
275 | tun = &tuners[t->type]; | ||
276 | if (freq < tun->thresh1) { | ||
277 | config = tun->VHF_L; | ||
278 | tuner_dbg("tv: VHF lowrange\n"); | ||
279 | } else if (freq < tun->thresh2) { | ||
280 | config = tun->VHF_H; | ||
281 | tuner_dbg("tv: VHF high range\n"); | ||
282 | } else { | ||
283 | config = tun->UHF; | ||
284 | tuner_dbg("tv: UHF range\n"); | ||
285 | } | ||
286 | |||
287 | |||
288 | /* tv norm specific stuff for multi-norm tuners */ | ||
289 | switch (t->type) { | ||
290 | case TUNER_PHILIPS_SECAM: // FI1216MF | ||
291 | /* 0x01 -> ??? no change ??? */ | ||
292 | /* 0x02 -> PAL BDGHI / SECAM L */ | ||
293 | /* 0x04 -> ??? PAL others / SECAM others ??? */ | ||
294 | config &= ~0x02; | ||
295 | if (t->std & V4L2_STD_SECAM) | ||
296 | config |= 0x02; | ||
297 | break; | ||
298 | |||
299 | case TUNER_TEMIC_4046FM5: | ||
300 | config &= ~0x0f; | ||
301 | |||
302 | if (t->std & V4L2_STD_PAL_BG) { | ||
303 | config |= TEMIC_SET_PAL_BG; | ||
304 | |||
305 | } else if (t->std & V4L2_STD_PAL_I) { | ||
306 | config |= TEMIC_SET_PAL_I; | ||
307 | |||
308 | } else if (t->std & V4L2_STD_PAL_DK) { | ||
309 | config |= TEMIC_SET_PAL_DK; | ||
310 | |||
311 | } else if (t->std & V4L2_STD_SECAM_L) { | ||
312 | config |= TEMIC_SET_PAL_L; | ||
313 | |||
314 | } | ||
315 | break; | ||
316 | |||
317 | case TUNER_PHILIPS_FQ1216ME: | ||
318 | config &= ~0x0f; | ||
319 | |||
320 | if (t->std & (V4L2_STD_PAL_BG|V4L2_STD_PAL_DK)) { | ||
321 | config |= PHILIPS_SET_PAL_BGDK; | ||
322 | |||
323 | } else if (t->std & V4L2_STD_PAL_I) { | ||
324 | config |= PHILIPS_SET_PAL_I; | ||
325 | |||
326 | } else if (t->std & V4L2_STD_SECAM_L) { | ||
327 | config |= PHILIPS_SET_PAL_L; | ||
328 | |||
329 | } | ||
330 | break; | ||
331 | |||
332 | case TUNER_PHILIPS_ATSC: | ||
333 | /* 0x00 -> ATSC antenna input 1 */ | ||
334 | /* 0x01 -> ATSC antenna input 2 */ | ||
335 | /* 0x02 -> NTSC antenna input 1 */ | ||
336 | /* 0x03 -> NTSC antenna input 2 */ | ||
337 | config &= ~0x03; | ||
338 | if (!(t->std & V4L2_STD_ATSC)) | ||
339 | config |= 2; | ||
340 | /* FIXME: input */ | ||
341 | break; | ||
342 | |||
343 | case TUNER_MICROTUNE_4042FI5: | ||
344 | /* Set the charge pump for fast tuning */ | ||
345 | tun->config |= 0x40; | ||
346 | break; | ||
347 | } | ||
348 | |||
349 | /* | ||
350 | * Philips FI1216MK2 remark from specification : | ||
351 | * for channel selection involving band switching, and to ensure | ||
352 | * smooth tuning to the desired channel without causing | ||
353 | * unnecessary charge pump action, it is recommended to consider | ||
354 | * the difference between wanted channel frequency and the | ||
355 | * current channel frequency. Unnecessary charge pump action | ||
356 | * will result in very low tuning voltage which may drive the | ||
357 | * oscillator to extreme conditions. | ||
358 | * | ||
359 | * Progfou: specification says to send config data before | ||
360 | * frequency in case (wanted frequency < current frequency). | ||
361 | */ | ||
362 | |||
363 | div=freq + tun->IFPCoff; | ||
364 | if (t->type == TUNER_PHILIPS_SECAM && freq < t->freq) { | ||
365 | buffer[0] = tun->config; | ||
366 | buffer[1] = config; | ||
367 | buffer[2] = (div>>8) & 0x7f; | ||
368 | buffer[3] = div & 0xff; | ||
369 | } else { | ||
370 | buffer[0] = (div>>8) & 0x7f; | ||
371 | buffer[1] = div & 0xff; | ||
372 | buffer[2] = tun->config; | ||
373 | buffer[3] = config; | ||
374 | } | ||
375 | tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n", | ||
376 | buffer[0],buffer[1],buffer[2],buffer[3]); | ||
377 | |||
378 | if (4 != (rc = i2c_master_send(c,buffer,4))) | ||
379 | tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); | ||
380 | |||
381 | if (t->type == TUNER_MICROTUNE_4042FI5) { | ||
382 | // FIXME - this may also work for other tuners | ||
383 | unsigned long timeout = jiffies + msecs_to_jiffies(1); | ||
384 | u8 status_byte = 0; | ||
385 | |||
386 | /* Wait until the PLL locks */ | ||
387 | for (;;) { | ||
388 | if (time_after(jiffies,timeout)) | ||
389 | return; | ||
390 | if (1 != (rc = i2c_master_recv(c,&status_byte,1))) { | ||
391 | tuner_warn("i2c i/o read error: rc == %d (should be 1)\n",rc); | ||
392 | break; | ||
393 | } | ||
394 | /* bit 6 is PLL locked indicator */ | ||
395 | if (status_byte & 0x40) | ||
396 | break; | ||
397 | udelay(10); | ||
398 | } | ||
399 | |||
400 | /* Set the charge pump for optimized phase noise figure */ | ||
401 | tun->config &= ~0x40; | ||
402 | buffer[0] = (div>>8) & 0x7f; | ||
403 | buffer[1] = div & 0xff; | ||
404 | buffer[2] = tun->config; | ||
405 | buffer[3] = config; | ||
406 | tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n", | ||
407 | buffer[0],buffer[1],buffer[2],buffer[3]); | ||
408 | |||
409 | if (4 != (rc = i2c_master_send(c,buffer,4))) | ||
410 | tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); | ||
411 | } | ||
412 | } | ||
413 | |||
414 | static void default_set_radio_freq(struct i2c_client *c, unsigned int freq) | ||
415 | { | ||
416 | struct tunertype *tun; | ||
417 | struct tuner *t = i2c_get_clientdata(c); | ||
418 | unsigned char buffer[4]; | ||
419 | unsigned div; | ||
420 | int rc; | ||
421 | |||
422 | tun=&tuners[t->type]; | ||
423 | div = freq + (int)(16*10.7); | ||
424 | buffer[2] = tun->config; | ||
425 | |||
426 | switch (t->type) { | ||
427 | case TUNER_PHILIPS_FM1216ME_MK3: | ||
428 | case TUNER_PHILIPS_FM1236_MK3: | ||
429 | buffer[3] = 0x19; | ||
430 | break; | ||
431 | case TUNER_PHILIPS_FM1256_IH3: | ||
432 | div = (20 * freq)/16 + 333 * 2; | ||
433 | buffer[2] = 0x80; | ||
434 | buffer[3] = 0x19; | ||
435 | break; | ||
436 | case TUNER_LG_PAL_FM: | ||
437 | buffer[3] = 0xa5; | ||
438 | break; | ||
439 | default: | ||
440 | buffer[3] = 0xa4; | ||
441 | break; | ||
442 | } | ||
443 | buffer[0] = (div>>8) & 0x7f; | ||
444 | buffer[1] = div & 0xff; | ||
445 | |||
446 | tuner_dbg("radio 0x%02x 0x%02x 0x%02x 0x%02x\n", | ||
447 | buffer[0],buffer[1],buffer[2],buffer[3]); | ||
448 | |||
449 | if (4 != (rc = i2c_master_send(c,buffer,4))) | ||
450 | tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc); | ||
451 | } | ||
452 | |||
453 | int default_tuner_init(struct i2c_client *c) | ||
454 | { | ||
455 | struct tuner *t = i2c_get_clientdata(c); | ||
456 | |||
457 | tuner_info("type set to %d (%s)\n", | ||
458 | t->type, tuners[t->type].name); | ||
459 | strlcpy(c->name, tuners[t->type].name, sizeof(c->name)); | ||
460 | |||
461 | t->tv_freq = default_set_tv_freq; | ||
462 | t->radio_freq = default_set_radio_freq; | ||
463 | t->has_signal = tuner_signal; | ||
464 | t->is_stereo = tuner_stereo; | ||
465 | return 0; | ||
466 | } | ||
467 | |||
468 | /* | ||
469 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
470 | * --------------------------------------------------------------------------- | ||
471 | * Local variables: | ||
472 | * c-basic-offset: 8 | ||
473 | * End: | ||
474 | */ | ||