diff options
Diffstat (limited to 'drivers/media/common/tuners/tda8290.c')
-rw-r--r-- | drivers/media/common/tuners/tda8290.c | 804 |
1 files changed, 804 insertions, 0 deletions
diff --git a/drivers/media/common/tuners/tda8290.c b/drivers/media/common/tuners/tda8290.c new file mode 100644 index 000000000000..91204d3f282d --- /dev/null +++ b/drivers/media/common/tuners/tda8290.c | |||
@@ -0,0 +1,804 @@ | |||
1 | /* | ||
2 | |||
3 | i2c tv tuner chip device driver | ||
4 | controls the philips tda8290+75 tuner chip combo. | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | |||
20 | This "tda8290" module was split apart from the original "tuner" module. | ||
21 | */ | ||
22 | |||
23 | #include <linux/i2c.h> | ||
24 | #include <linux/delay.h> | ||
25 | #include <linux/videodev.h> | ||
26 | #include "tuner-i2c.h" | ||
27 | #include "tda8290.h" | ||
28 | #include "tda827x.h" | ||
29 | #include "tda18271.h" | ||
30 | |||
31 | static int debug; | ||
32 | module_param(debug, int, 0644); | ||
33 | MODULE_PARM_DESC(debug, "enable verbose debug messages"); | ||
34 | |||
35 | /* ---------------------------------------------------------------------- */ | ||
36 | |||
37 | struct tda8290_priv { | ||
38 | struct tuner_i2c_props i2c_props; | ||
39 | |||
40 | unsigned char tda8290_easy_mode; | ||
41 | |||
42 | unsigned char tda827x_addr; | ||
43 | |||
44 | unsigned char ver; | ||
45 | #define TDA8290 1 | ||
46 | #define TDA8295 2 | ||
47 | #define TDA8275 4 | ||
48 | #define TDA8275A 8 | ||
49 | #define TDA18271 16 | ||
50 | |||
51 | struct tda827x_config cfg; | ||
52 | }; | ||
53 | |||
54 | /*---------------------------------------------------------------------*/ | ||
55 | |||
56 | static int tda8290_i2c_bridge(struct dvb_frontend *fe, int close) | ||
57 | { | ||
58 | struct tda8290_priv *priv = fe->analog_demod_priv; | ||
59 | |||
60 | unsigned char enable[2] = { 0x21, 0xC0 }; | ||
61 | unsigned char disable[2] = { 0x21, 0x00 }; | ||
62 | unsigned char *msg; | ||
63 | |||
64 | if (close) { | ||
65 | msg = enable; | ||
66 | tuner_i2c_xfer_send(&priv->i2c_props, msg, 2); | ||
67 | /* let the bridge stabilize */ | ||
68 | msleep(20); | ||
69 | } else { | ||
70 | msg = disable; | ||
71 | tuner_i2c_xfer_send(&priv->i2c_props, msg, 2); | ||
72 | } | ||
73 | |||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | static int tda8295_i2c_bridge(struct dvb_frontend *fe, int close) | ||
78 | { | ||
79 | struct tda8290_priv *priv = fe->analog_demod_priv; | ||
80 | |||
81 | unsigned char enable[2] = { 0x45, 0xc1 }; | ||
82 | unsigned char disable[2] = { 0x46, 0x00 }; | ||
83 | unsigned char buf[3] = { 0x45, 0x01, 0x00 }; | ||
84 | unsigned char *msg; | ||
85 | |||
86 | if (close) { | ||
87 | msg = enable; | ||
88 | tuner_i2c_xfer_send(&priv->i2c_props, msg, 2); | ||
89 | /* let the bridge stabilize */ | ||
90 | msleep(20); | ||
91 | } else { | ||
92 | msg = disable; | ||
93 | tuner_i2c_xfer_send(&priv->i2c_props, msg, 1); | ||
94 | tuner_i2c_xfer_recv(&priv->i2c_props, &msg[1], 1); | ||
95 | |||
96 | buf[2] = msg[1]; | ||
97 | buf[2] &= ~0x04; | ||
98 | tuner_i2c_xfer_send(&priv->i2c_props, buf, 3); | ||
99 | msleep(5); | ||
100 | |||
101 | msg[1] |= 0x04; | ||
102 | tuner_i2c_xfer_send(&priv->i2c_props, msg, 2); | ||
103 | } | ||
104 | |||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | /*---------------------------------------------------------------------*/ | ||
109 | |||
110 | static void set_audio(struct dvb_frontend *fe, | ||
111 | struct analog_parameters *params) | ||
112 | { | ||
113 | struct tda8290_priv *priv = fe->analog_demod_priv; | ||
114 | char* mode; | ||
115 | |||
116 | if (params->std & V4L2_STD_MN) { | ||
117 | priv->tda8290_easy_mode = 0x01; | ||
118 | mode = "MN"; | ||
119 | } else if (params->std & V4L2_STD_B) { | ||
120 | priv->tda8290_easy_mode = 0x02; | ||
121 | mode = "B"; | ||
122 | } else if (params->std & V4L2_STD_GH) { | ||
123 | priv->tda8290_easy_mode = 0x04; | ||
124 | mode = "GH"; | ||
125 | } else if (params->std & V4L2_STD_PAL_I) { | ||
126 | priv->tda8290_easy_mode = 0x08; | ||
127 | mode = "I"; | ||
128 | } else if (params->std & V4L2_STD_DK) { | ||
129 | priv->tda8290_easy_mode = 0x10; | ||
130 | mode = "DK"; | ||
131 | } else if (params->std & V4L2_STD_SECAM_L) { | ||
132 | priv->tda8290_easy_mode = 0x20; | ||
133 | mode = "L"; | ||
134 | } else if (params->std & V4L2_STD_SECAM_LC) { | ||
135 | priv->tda8290_easy_mode = 0x40; | ||
136 | mode = "LC"; | ||
137 | } else { | ||
138 | priv->tda8290_easy_mode = 0x10; | ||
139 | mode = "xx"; | ||
140 | } | ||
141 | |||
142 | tuner_dbg("setting tda829x to system %s\n", mode); | ||
143 | } | ||
144 | |||
145 | static void tda8290_set_params(struct dvb_frontend *fe, | ||
146 | struct analog_parameters *params) | ||
147 | { | ||
148 | struct tda8290_priv *priv = fe->analog_demod_priv; | ||
149 | |||
150 | unsigned char soft_reset[] = { 0x00, 0x00 }; | ||
151 | unsigned char easy_mode[] = { 0x01, priv->tda8290_easy_mode }; | ||
152 | unsigned char expert_mode[] = { 0x01, 0x80 }; | ||
153 | unsigned char agc_out_on[] = { 0x02, 0x00 }; | ||
154 | unsigned char gainset_off[] = { 0x28, 0x14 }; | ||
155 | unsigned char if_agc_spd[] = { 0x0f, 0x88 }; | ||
156 | unsigned char adc_head_6[] = { 0x05, 0x04 }; | ||
157 | unsigned char adc_head_9[] = { 0x05, 0x02 }; | ||
158 | unsigned char adc_head_12[] = { 0x05, 0x01 }; | ||
159 | unsigned char pll_bw_nom[] = { 0x0d, 0x47 }; | ||
160 | unsigned char pll_bw_low[] = { 0x0d, 0x27 }; | ||
161 | unsigned char gainset_2[] = { 0x28, 0x64 }; | ||
162 | unsigned char agc_rst_on[] = { 0x0e, 0x0b }; | ||
163 | unsigned char agc_rst_off[] = { 0x0e, 0x09 }; | ||
164 | unsigned char if_agc_set[] = { 0x0f, 0x81 }; | ||
165 | unsigned char addr_adc_sat = 0x1a; | ||
166 | unsigned char addr_agc_stat = 0x1d; | ||
167 | unsigned char addr_pll_stat = 0x1b; | ||
168 | unsigned char adc_sat, agc_stat, | ||
169 | pll_stat; | ||
170 | int i; | ||
171 | |||
172 | set_audio(fe, params); | ||
173 | |||
174 | if (priv->cfg.config) | ||
175 | tuner_dbg("tda827xa config is 0x%02x\n", priv->cfg.config); | ||
176 | tuner_i2c_xfer_send(&priv->i2c_props, easy_mode, 2); | ||
177 | tuner_i2c_xfer_send(&priv->i2c_props, agc_out_on, 2); | ||
178 | tuner_i2c_xfer_send(&priv->i2c_props, soft_reset, 2); | ||
179 | msleep(1); | ||
180 | |||
181 | expert_mode[1] = priv->tda8290_easy_mode + 0x80; | ||
182 | tuner_i2c_xfer_send(&priv->i2c_props, expert_mode, 2); | ||
183 | tuner_i2c_xfer_send(&priv->i2c_props, gainset_off, 2); | ||
184 | tuner_i2c_xfer_send(&priv->i2c_props, if_agc_spd, 2); | ||
185 | if (priv->tda8290_easy_mode & 0x60) | ||
186 | tuner_i2c_xfer_send(&priv->i2c_props, adc_head_9, 2); | ||
187 | else | ||
188 | tuner_i2c_xfer_send(&priv->i2c_props, adc_head_6, 2); | ||
189 | tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_nom, 2); | ||
190 | |||
191 | tda8290_i2c_bridge(fe, 1); | ||
192 | |||
193 | if (fe->ops.tuner_ops.set_analog_params) | ||
194 | fe->ops.tuner_ops.set_analog_params(fe, params); | ||
195 | |||
196 | for (i = 0; i < 3; i++) { | ||
197 | tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1); | ||
198 | tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1); | ||
199 | if (pll_stat & 0x80) { | ||
200 | tuner_i2c_xfer_send(&priv->i2c_props, &addr_adc_sat, 1); | ||
201 | tuner_i2c_xfer_recv(&priv->i2c_props, &adc_sat, 1); | ||
202 | tuner_i2c_xfer_send(&priv->i2c_props, &addr_agc_stat, 1); | ||
203 | tuner_i2c_xfer_recv(&priv->i2c_props, &agc_stat, 1); | ||
204 | tuner_dbg("tda8290 is locked, AGC: %d\n", agc_stat); | ||
205 | break; | ||
206 | } else { | ||
207 | tuner_dbg("tda8290 not locked, no signal?\n"); | ||
208 | msleep(100); | ||
209 | } | ||
210 | } | ||
211 | /* adjust headroom resp. gain */ | ||
212 | if ((agc_stat > 115) || (!(pll_stat & 0x80) && (adc_sat < 20))) { | ||
213 | tuner_dbg("adjust gain, step 1. Agc: %d, ADC stat: %d, lock: %d\n", | ||
214 | agc_stat, adc_sat, pll_stat & 0x80); | ||
215 | tuner_i2c_xfer_send(&priv->i2c_props, gainset_2, 2); | ||
216 | msleep(100); | ||
217 | tuner_i2c_xfer_send(&priv->i2c_props, &addr_agc_stat, 1); | ||
218 | tuner_i2c_xfer_recv(&priv->i2c_props, &agc_stat, 1); | ||
219 | tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1); | ||
220 | tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1); | ||
221 | if ((agc_stat > 115) || !(pll_stat & 0x80)) { | ||
222 | tuner_dbg("adjust gain, step 2. Agc: %d, lock: %d\n", | ||
223 | agc_stat, pll_stat & 0x80); | ||
224 | if (priv->cfg.agcf) | ||
225 | priv->cfg.agcf(fe); | ||
226 | msleep(100); | ||
227 | tuner_i2c_xfer_send(&priv->i2c_props, &addr_agc_stat, 1); | ||
228 | tuner_i2c_xfer_recv(&priv->i2c_props, &agc_stat, 1); | ||
229 | tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1); | ||
230 | tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1); | ||
231 | if((agc_stat > 115) || !(pll_stat & 0x80)) { | ||
232 | tuner_dbg("adjust gain, step 3. Agc: %d\n", agc_stat); | ||
233 | tuner_i2c_xfer_send(&priv->i2c_props, adc_head_12, 2); | ||
234 | tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_low, 2); | ||
235 | msleep(100); | ||
236 | } | ||
237 | } | ||
238 | } | ||
239 | |||
240 | /* l/ l' deadlock? */ | ||
241 | if(priv->tda8290_easy_mode & 0x60) { | ||
242 | tuner_i2c_xfer_send(&priv->i2c_props, &addr_adc_sat, 1); | ||
243 | tuner_i2c_xfer_recv(&priv->i2c_props, &adc_sat, 1); | ||
244 | tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1); | ||
245 | tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1); | ||
246 | if ((adc_sat > 20) || !(pll_stat & 0x80)) { | ||
247 | tuner_dbg("trying to resolve SECAM L deadlock\n"); | ||
248 | tuner_i2c_xfer_send(&priv->i2c_props, agc_rst_on, 2); | ||
249 | msleep(40); | ||
250 | tuner_i2c_xfer_send(&priv->i2c_props, agc_rst_off, 2); | ||
251 | } | ||
252 | } | ||
253 | |||
254 | tda8290_i2c_bridge(fe, 0); | ||
255 | tuner_i2c_xfer_send(&priv->i2c_props, if_agc_set, 2); | ||
256 | } | ||
257 | |||
258 | /*---------------------------------------------------------------------*/ | ||
259 | |||
260 | static void tda8295_power(struct dvb_frontend *fe, int enable) | ||
261 | { | ||
262 | struct tda8290_priv *priv = fe->analog_demod_priv; | ||
263 | unsigned char buf[] = { 0x30, 0x00 }; /* clb_stdbt */ | ||
264 | |||
265 | tuner_i2c_xfer_send(&priv->i2c_props, &buf[0], 1); | ||
266 | tuner_i2c_xfer_recv(&priv->i2c_props, &buf[1], 1); | ||
267 | |||
268 | if (enable) | ||
269 | buf[1] = 0x01; | ||
270 | else | ||
271 | buf[1] = 0x03; | ||
272 | |||
273 | tuner_i2c_xfer_send(&priv->i2c_props, buf, 2); | ||
274 | } | ||
275 | |||
276 | static void tda8295_set_easy_mode(struct dvb_frontend *fe, int enable) | ||
277 | { | ||
278 | struct tda8290_priv *priv = fe->analog_demod_priv; | ||
279 | unsigned char buf[] = { 0x01, 0x00 }; | ||
280 | |||
281 | tuner_i2c_xfer_send(&priv->i2c_props, &buf[0], 1); | ||
282 | tuner_i2c_xfer_recv(&priv->i2c_props, &buf[1], 1); | ||
283 | |||
284 | if (enable) | ||
285 | buf[1] = 0x01; /* rising edge sets regs 0x02 - 0x23 */ | ||
286 | else | ||
287 | buf[1] = 0x00; /* reset active bit */ | ||
288 | |||
289 | tuner_i2c_xfer_send(&priv->i2c_props, buf, 2); | ||
290 | } | ||
291 | |||
292 | static void tda8295_set_video_std(struct dvb_frontend *fe) | ||
293 | { | ||
294 | struct tda8290_priv *priv = fe->analog_demod_priv; | ||
295 | unsigned char buf[] = { 0x00, priv->tda8290_easy_mode }; | ||
296 | |||
297 | tuner_i2c_xfer_send(&priv->i2c_props, buf, 2); | ||
298 | |||
299 | tda8295_set_easy_mode(fe, 1); | ||
300 | msleep(20); | ||
301 | tda8295_set_easy_mode(fe, 0); | ||
302 | } | ||
303 | |||
304 | /*---------------------------------------------------------------------*/ | ||
305 | |||
306 | static void tda8295_agc1_out(struct dvb_frontend *fe, int enable) | ||
307 | { | ||
308 | struct tda8290_priv *priv = fe->analog_demod_priv; | ||
309 | unsigned char buf[] = { 0x02, 0x00 }; /* DIV_FUNC */ | ||
310 | |||
311 | tuner_i2c_xfer_send(&priv->i2c_props, &buf[0], 1); | ||
312 | tuner_i2c_xfer_recv(&priv->i2c_props, &buf[1], 1); | ||
313 | |||
314 | if (enable) | ||
315 | buf[1] &= ~0x40; | ||
316 | else | ||
317 | buf[1] |= 0x40; | ||
318 | |||
319 | tuner_i2c_xfer_send(&priv->i2c_props, buf, 2); | ||
320 | } | ||
321 | |||
322 | static void tda8295_agc2_out(struct dvb_frontend *fe, int enable) | ||
323 | { | ||
324 | struct tda8290_priv *priv = fe->analog_demod_priv; | ||
325 | unsigned char set_gpio_cf[] = { 0x44, 0x00 }; | ||
326 | unsigned char set_gpio_val[] = { 0x46, 0x00 }; | ||
327 | |||
328 | tuner_i2c_xfer_send(&priv->i2c_props, &set_gpio_cf[0], 1); | ||
329 | tuner_i2c_xfer_recv(&priv->i2c_props, &set_gpio_cf[1], 1); | ||
330 | tuner_i2c_xfer_send(&priv->i2c_props, &set_gpio_val[0], 1); | ||
331 | tuner_i2c_xfer_recv(&priv->i2c_props, &set_gpio_val[1], 1); | ||
332 | |||
333 | set_gpio_cf[1] &= 0xf0; /* clear GPIO_0 bits 3-0 */ | ||
334 | |||
335 | if (enable) { | ||
336 | set_gpio_cf[1] |= 0x01; /* config GPIO_0 as Open Drain Out */ | ||
337 | set_gpio_val[1] &= 0xfe; /* set GPIO_0 pin low */ | ||
338 | } | ||
339 | tuner_i2c_xfer_send(&priv->i2c_props, set_gpio_cf, 2); | ||
340 | tuner_i2c_xfer_send(&priv->i2c_props, set_gpio_val, 2); | ||
341 | } | ||
342 | |||
343 | static int tda8295_has_signal(struct dvb_frontend *fe) | ||
344 | { | ||
345 | struct tda8290_priv *priv = fe->analog_demod_priv; | ||
346 | |||
347 | unsigned char hvpll_stat = 0x26; | ||
348 | unsigned char ret; | ||
349 | |||
350 | tuner_i2c_xfer_send(&priv->i2c_props, &hvpll_stat, 1); | ||
351 | tuner_i2c_xfer_recv(&priv->i2c_props, &ret, 1); | ||
352 | return (ret & 0x01) ? 65535 : 0; | ||
353 | } | ||
354 | |||
355 | /*---------------------------------------------------------------------*/ | ||
356 | |||
357 | static void tda8295_set_params(struct dvb_frontend *fe, | ||
358 | struct analog_parameters *params) | ||
359 | { | ||
360 | struct tda8290_priv *priv = fe->analog_demod_priv; | ||
361 | |||
362 | unsigned char blanking_mode[] = { 0x1d, 0x00 }; | ||
363 | |||
364 | set_audio(fe, params); | ||
365 | |||
366 | tuner_dbg("%s: freq = %d\n", __func__, params->frequency); | ||
367 | |||
368 | tda8295_power(fe, 1); | ||
369 | tda8295_agc1_out(fe, 1); | ||
370 | |||
371 | tuner_i2c_xfer_send(&priv->i2c_props, &blanking_mode[0], 1); | ||
372 | tuner_i2c_xfer_recv(&priv->i2c_props, &blanking_mode[1], 1); | ||
373 | |||
374 | tda8295_set_video_std(fe); | ||
375 | |||
376 | blanking_mode[1] = 0x03; | ||
377 | tuner_i2c_xfer_send(&priv->i2c_props, blanking_mode, 2); | ||
378 | msleep(20); | ||
379 | |||
380 | tda8295_i2c_bridge(fe, 1); | ||
381 | |||
382 | if (fe->ops.tuner_ops.set_analog_params) | ||
383 | fe->ops.tuner_ops.set_analog_params(fe, params); | ||
384 | |||
385 | if (priv->cfg.agcf) | ||
386 | priv->cfg.agcf(fe); | ||
387 | |||
388 | if (tda8295_has_signal(fe)) | ||
389 | tuner_dbg("tda8295 is locked\n"); | ||
390 | else | ||
391 | tuner_dbg("tda8295 not locked, no signal?\n"); | ||
392 | |||
393 | tda8295_i2c_bridge(fe, 0); | ||
394 | } | ||
395 | |||
396 | /*---------------------------------------------------------------------*/ | ||
397 | |||
398 | static int tda8290_has_signal(struct dvb_frontend *fe) | ||
399 | { | ||
400 | struct tda8290_priv *priv = fe->analog_demod_priv; | ||
401 | |||
402 | unsigned char i2c_get_afc[1] = { 0x1B }; | ||
403 | unsigned char afc = 0; | ||
404 | |||
405 | tuner_i2c_xfer_send(&priv->i2c_props, i2c_get_afc, ARRAY_SIZE(i2c_get_afc)); | ||
406 | tuner_i2c_xfer_recv(&priv->i2c_props, &afc, 1); | ||
407 | return (afc & 0x80)? 65535:0; | ||
408 | } | ||
409 | |||
410 | /*---------------------------------------------------------------------*/ | ||
411 | |||
412 | static void tda8290_standby(struct dvb_frontend *fe) | ||
413 | { | ||
414 | struct tda8290_priv *priv = fe->analog_demod_priv; | ||
415 | |||
416 | unsigned char cb1[] = { 0x30, 0xD0 }; | ||
417 | unsigned char tda8290_standby[] = { 0x00, 0x02 }; | ||
418 | unsigned char tda8290_agc_tri[] = { 0x02, 0x20 }; | ||
419 | struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags=0, .buf=cb1, .len = 2}; | ||
420 | |||
421 | tda8290_i2c_bridge(fe, 1); | ||
422 | if (priv->ver & TDA8275A) | ||
423 | cb1[1] = 0x90; | ||
424 | i2c_transfer(priv->i2c_props.adap, &msg, 1); | ||
425 | tda8290_i2c_bridge(fe, 0); | ||
426 | tuner_i2c_xfer_send(&priv->i2c_props, tda8290_agc_tri, 2); | ||
427 | tuner_i2c_xfer_send(&priv->i2c_props, tda8290_standby, 2); | ||
428 | } | ||
429 | |||
430 | static void tda8295_standby(struct dvb_frontend *fe) | ||
431 | { | ||
432 | tda8295_agc1_out(fe, 0); /* Put AGC in tri-state */ | ||
433 | |||
434 | tda8295_power(fe, 0); | ||
435 | } | ||
436 | |||
437 | static void tda8290_init_if(struct dvb_frontend *fe) | ||
438 | { | ||
439 | struct tda8290_priv *priv = fe->analog_demod_priv; | ||
440 | |||
441 | unsigned char set_VS[] = { 0x30, 0x6F }; | ||
442 | unsigned char set_GP00_CF[] = { 0x20, 0x01 }; | ||
443 | unsigned char set_GP01_CF[] = { 0x20, 0x0B }; | ||
444 | |||
445 | if ((priv->cfg.config == 1) || (priv->cfg.config == 2)) | ||
446 | tuner_i2c_xfer_send(&priv->i2c_props, set_GP00_CF, 2); | ||
447 | else | ||
448 | tuner_i2c_xfer_send(&priv->i2c_props, set_GP01_CF, 2); | ||
449 | tuner_i2c_xfer_send(&priv->i2c_props, set_VS, 2); | ||
450 | } | ||
451 | |||
452 | static void tda8295_init_if(struct dvb_frontend *fe) | ||
453 | { | ||
454 | struct tda8290_priv *priv = fe->analog_demod_priv; | ||
455 | |||
456 | static unsigned char set_adc_ctl[] = { 0x33, 0x14 }; | ||
457 | static unsigned char set_adc_ctl2[] = { 0x34, 0x00 }; | ||
458 | static unsigned char set_pll_reg6[] = { 0x3e, 0x63 }; | ||
459 | static unsigned char set_pll_reg0[] = { 0x38, 0x23 }; | ||
460 | static unsigned char set_pll_reg7[] = { 0x3f, 0x01 }; | ||
461 | static unsigned char set_pll_reg10[] = { 0x42, 0x61 }; | ||
462 | static unsigned char set_gpio_reg0[] = { 0x44, 0x0b }; | ||
463 | |||
464 | tda8295_power(fe, 1); | ||
465 | |||
466 | tda8295_set_easy_mode(fe, 0); | ||
467 | tda8295_set_video_std(fe); | ||
468 | |||
469 | tuner_i2c_xfer_send(&priv->i2c_props, set_adc_ctl, 2); | ||
470 | tuner_i2c_xfer_send(&priv->i2c_props, set_adc_ctl2, 2); | ||
471 | tuner_i2c_xfer_send(&priv->i2c_props, set_pll_reg6, 2); | ||
472 | tuner_i2c_xfer_send(&priv->i2c_props, set_pll_reg0, 2); | ||
473 | tuner_i2c_xfer_send(&priv->i2c_props, set_pll_reg7, 2); | ||
474 | tuner_i2c_xfer_send(&priv->i2c_props, set_pll_reg10, 2); | ||
475 | tuner_i2c_xfer_send(&priv->i2c_props, set_gpio_reg0, 2); | ||
476 | |||
477 | tda8295_agc1_out(fe, 0); | ||
478 | tda8295_agc2_out(fe, 0); | ||
479 | } | ||
480 | |||
481 | static void tda8290_init_tuner(struct dvb_frontend *fe) | ||
482 | { | ||
483 | struct tda8290_priv *priv = fe->analog_demod_priv; | ||
484 | unsigned char tda8275_init[] = { 0x00, 0x00, 0x00, 0x40, 0xdC, 0x04, 0xAf, | ||
485 | 0x3F, 0x2A, 0x04, 0xFF, 0x00, 0x00, 0x40 }; | ||
486 | unsigned char tda8275a_init[] = { 0x00, 0x00, 0x00, 0x00, 0xdC, 0x05, 0x8b, | ||
487 | 0x0c, 0x04, 0x20, 0xFF, 0x00, 0x00, 0x4b }; | ||
488 | struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags=0, | ||
489 | .buf=tda8275_init, .len = 14}; | ||
490 | if (priv->ver & TDA8275A) | ||
491 | msg.buf = tda8275a_init; | ||
492 | |||
493 | tda8290_i2c_bridge(fe, 1); | ||
494 | i2c_transfer(priv->i2c_props.adap, &msg, 1); | ||
495 | tda8290_i2c_bridge(fe, 0); | ||
496 | } | ||
497 | |||
498 | /*---------------------------------------------------------------------*/ | ||
499 | |||
500 | static void tda829x_release(struct dvb_frontend *fe) | ||
501 | { | ||
502 | struct tda8290_priv *priv = fe->analog_demod_priv; | ||
503 | |||
504 | /* only try to release the tuner if we've | ||
505 | * attached it from within this module */ | ||
506 | if (priv->ver & (TDA18271 | TDA8275 | TDA8275A)) | ||
507 | if (fe->ops.tuner_ops.release) | ||
508 | fe->ops.tuner_ops.release(fe); | ||
509 | |||
510 | kfree(fe->analog_demod_priv); | ||
511 | fe->analog_demod_priv = NULL; | ||
512 | } | ||
513 | |||
514 | static struct tda18271_config tda829x_tda18271_config = { | ||
515 | .gate = TDA18271_GATE_ANALOG, | ||
516 | }; | ||
517 | |||
518 | static int tda829x_find_tuner(struct dvb_frontend *fe) | ||
519 | { | ||
520 | struct tda8290_priv *priv = fe->analog_demod_priv; | ||
521 | struct analog_demod_ops *analog_ops = &fe->ops.analog_ops; | ||
522 | int i, ret, tuners_found; | ||
523 | u32 tuner_addrs; | ||
524 | u8 data; | ||
525 | struct i2c_msg msg = { .flags = I2C_M_RD, .buf = &data, .len = 1 }; | ||
526 | |||
527 | if (NULL == analog_ops->i2c_gate_ctrl) | ||
528 | return -EINVAL; | ||
529 | |||
530 | analog_ops->i2c_gate_ctrl(fe, 1); | ||
531 | |||
532 | /* probe for tuner chip */ | ||
533 | tuners_found = 0; | ||
534 | tuner_addrs = 0; | ||
535 | for (i = 0x60; i <= 0x63; i++) { | ||
536 | msg.addr = i; | ||
537 | ret = i2c_transfer(priv->i2c_props.adap, &msg, 1); | ||
538 | if (ret == 1) { | ||
539 | tuners_found++; | ||
540 | tuner_addrs = (tuner_addrs << 8) + i; | ||
541 | } | ||
542 | } | ||
543 | /* if there is more than one tuner, we expect the right one is | ||
544 | behind the bridge and we choose the highest address that doesn't | ||
545 | give a response now | ||
546 | */ | ||
547 | |||
548 | analog_ops->i2c_gate_ctrl(fe, 0); | ||
549 | |||
550 | if (tuners_found > 1) | ||
551 | for (i = 0; i < tuners_found; i++) { | ||
552 | msg.addr = tuner_addrs & 0xff; | ||
553 | ret = i2c_transfer(priv->i2c_props.adap, &msg, 1); | ||
554 | if (ret == 1) | ||
555 | tuner_addrs = tuner_addrs >> 8; | ||
556 | else | ||
557 | break; | ||
558 | } | ||
559 | |||
560 | if (tuner_addrs == 0) { | ||
561 | tuner_addrs = 0x60; | ||
562 | tuner_info("could not clearly identify tuner address, " | ||
563 | "defaulting to %x\n", tuner_addrs); | ||
564 | } else { | ||
565 | tuner_addrs = tuner_addrs & 0xff; | ||
566 | tuner_info("setting tuner address to %x\n", tuner_addrs); | ||
567 | } | ||
568 | priv->tda827x_addr = tuner_addrs; | ||
569 | msg.addr = tuner_addrs; | ||
570 | |||
571 | analog_ops->i2c_gate_ctrl(fe, 1); | ||
572 | ret = i2c_transfer(priv->i2c_props.adap, &msg, 1); | ||
573 | |||
574 | if (ret != 1) { | ||
575 | tuner_warn("tuner access failed!\n"); | ||
576 | return -EREMOTEIO; | ||
577 | } | ||
578 | |||
579 | if ((data == 0x83) || (data == 0x84)) { | ||
580 | priv->ver |= TDA18271; | ||
581 | dvb_attach(tda18271_attach, fe, priv->tda827x_addr, | ||
582 | priv->i2c_props.adap, &tda829x_tda18271_config); | ||
583 | } else { | ||
584 | if ((data & 0x3c) == 0) | ||
585 | priv->ver |= TDA8275; | ||
586 | else | ||
587 | priv->ver |= TDA8275A; | ||
588 | |||
589 | dvb_attach(tda827x_attach, fe, priv->tda827x_addr, | ||
590 | priv->i2c_props.adap, &priv->cfg); | ||
591 | priv->cfg.switch_addr = priv->i2c_props.addr; | ||
592 | } | ||
593 | if (fe->ops.tuner_ops.init) | ||
594 | fe->ops.tuner_ops.init(fe); | ||
595 | |||
596 | if (fe->ops.tuner_ops.sleep) | ||
597 | fe->ops.tuner_ops.sleep(fe); | ||
598 | |||
599 | analog_ops->i2c_gate_ctrl(fe, 0); | ||
600 | |||
601 | return 0; | ||
602 | } | ||
603 | |||
604 | static int tda8290_probe(struct tuner_i2c_props *i2c_props) | ||
605 | { | ||
606 | #define TDA8290_ID 0x89 | ||
607 | unsigned char tda8290_id[] = { 0x1f, 0x00 }; | ||
608 | |||
609 | /* detect tda8290 */ | ||
610 | tuner_i2c_xfer_send(i2c_props, &tda8290_id[0], 1); | ||
611 | tuner_i2c_xfer_recv(i2c_props, &tda8290_id[1], 1); | ||
612 | |||
613 | if (tda8290_id[1] == TDA8290_ID) { | ||
614 | if (debug) | ||
615 | printk(KERN_DEBUG "%s: tda8290 detected @ %d-%04x\n", | ||
616 | __func__, i2c_adapter_id(i2c_props->adap), | ||
617 | i2c_props->addr); | ||
618 | return 0; | ||
619 | } | ||
620 | |||
621 | return -ENODEV; | ||
622 | } | ||
623 | |||
624 | static int tda8295_probe(struct tuner_i2c_props *i2c_props) | ||
625 | { | ||
626 | #define TDA8295_ID 0x8a | ||
627 | unsigned char tda8295_id[] = { 0x2f, 0x00 }; | ||
628 | |||
629 | /* detect tda8295 */ | ||
630 | tuner_i2c_xfer_send(i2c_props, &tda8295_id[0], 1); | ||
631 | tuner_i2c_xfer_recv(i2c_props, &tda8295_id[1], 1); | ||
632 | |||
633 | if (tda8295_id[1] == TDA8295_ID) { | ||
634 | if (debug) | ||
635 | printk(KERN_DEBUG "%s: tda8295 detected @ %d-%04x\n", | ||
636 | __func__, i2c_adapter_id(i2c_props->adap), | ||
637 | i2c_props->addr); | ||
638 | return 0; | ||
639 | } | ||
640 | |||
641 | return -ENODEV; | ||
642 | } | ||
643 | |||
644 | static struct analog_demod_ops tda8290_ops = { | ||
645 | .set_params = tda8290_set_params, | ||
646 | .has_signal = tda8290_has_signal, | ||
647 | .standby = tda8290_standby, | ||
648 | .release = tda829x_release, | ||
649 | .i2c_gate_ctrl = tda8290_i2c_bridge, | ||
650 | }; | ||
651 | |||
652 | static struct analog_demod_ops tda8295_ops = { | ||
653 | .set_params = tda8295_set_params, | ||
654 | .has_signal = tda8295_has_signal, | ||
655 | .standby = tda8295_standby, | ||
656 | .release = tda829x_release, | ||
657 | .i2c_gate_ctrl = tda8295_i2c_bridge, | ||
658 | }; | ||
659 | |||
660 | struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe, | ||
661 | struct i2c_adapter *i2c_adap, u8 i2c_addr, | ||
662 | struct tda829x_config *cfg) | ||
663 | { | ||
664 | struct tda8290_priv *priv = NULL; | ||
665 | char *name; | ||
666 | |||
667 | priv = kzalloc(sizeof(struct tda8290_priv), GFP_KERNEL); | ||
668 | if (priv == NULL) | ||
669 | return NULL; | ||
670 | fe->analog_demod_priv = priv; | ||
671 | |||
672 | priv->i2c_props.addr = i2c_addr; | ||
673 | priv->i2c_props.adap = i2c_adap; | ||
674 | priv->i2c_props.name = "tda829x"; | ||
675 | if (cfg) { | ||
676 | priv->cfg.config = cfg->lna_cfg; | ||
677 | priv->cfg.tuner_callback = cfg->tuner_callback; | ||
678 | } | ||
679 | |||
680 | if (tda8290_probe(&priv->i2c_props) == 0) { | ||
681 | priv->ver = TDA8290; | ||
682 | memcpy(&fe->ops.analog_ops, &tda8290_ops, | ||
683 | sizeof(struct analog_demod_ops)); | ||
684 | } | ||
685 | |||
686 | if (tda8295_probe(&priv->i2c_props) == 0) { | ||
687 | priv->ver = TDA8295; | ||
688 | memcpy(&fe->ops.analog_ops, &tda8295_ops, | ||
689 | sizeof(struct analog_demod_ops)); | ||
690 | } | ||
691 | |||
692 | if ((!(cfg) || (TDA829X_PROBE_TUNER == cfg->probe_tuner)) && | ||
693 | (tda829x_find_tuner(fe) < 0)) | ||
694 | goto fail; | ||
695 | |||
696 | switch (priv->ver) { | ||
697 | case TDA8290: | ||
698 | name = "tda8290"; | ||
699 | break; | ||
700 | case TDA8295: | ||
701 | name = "tda8295"; | ||
702 | break; | ||
703 | case TDA8290 | TDA8275: | ||
704 | name = "tda8290+75"; | ||
705 | break; | ||
706 | case TDA8295 | TDA8275: | ||
707 | name = "tda8295+75"; | ||
708 | break; | ||
709 | case TDA8290 | TDA8275A: | ||
710 | name = "tda8290+75a"; | ||
711 | break; | ||
712 | case TDA8295 | TDA8275A: | ||
713 | name = "tda8295+75a"; | ||
714 | break; | ||
715 | case TDA8290 | TDA18271: | ||
716 | name = "tda8290+18271"; | ||
717 | break; | ||
718 | case TDA8295 | TDA18271: | ||
719 | name = "tda8295+18271"; | ||
720 | break; | ||
721 | default: | ||
722 | goto fail; | ||
723 | } | ||
724 | tuner_info("type set to %s\n", name); | ||
725 | |||
726 | fe->ops.analog_ops.info.name = name; | ||
727 | |||
728 | if (priv->ver & TDA8290) { | ||
729 | tda8290_init_tuner(fe); | ||
730 | tda8290_init_if(fe); | ||
731 | } else if (priv->ver & TDA8295) | ||
732 | tda8295_init_if(fe); | ||
733 | |||
734 | return fe; | ||
735 | |||
736 | fail: | ||
737 | tda829x_release(fe); | ||
738 | return NULL; | ||
739 | } | ||
740 | EXPORT_SYMBOL_GPL(tda829x_attach); | ||
741 | |||
742 | int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr) | ||
743 | { | ||
744 | struct tuner_i2c_props i2c_props = { | ||
745 | .adap = i2c_adap, | ||
746 | .addr = i2c_addr, | ||
747 | }; | ||
748 | |||
749 | unsigned char soft_reset[] = { 0x00, 0x00 }; | ||
750 | unsigned char easy_mode_b[] = { 0x01, 0x02 }; | ||
751 | unsigned char easy_mode_g[] = { 0x01, 0x04 }; | ||
752 | unsigned char restore_9886[] = { 0x00, 0xd6, 0x30 }; | ||
753 | unsigned char addr_dto_lsb = 0x07; | ||
754 | unsigned char data; | ||
755 | #define PROBE_BUFFER_SIZE 8 | ||
756 | unsigned char buf[PROBE_BUFFER_SIZE]; | ||
757 | int i; | ||
758 | |||
759 | /* rule out tda9887, which would return the same byte repeatedly */ | ||
760 | tuner_i2c_xfer_send(&i2c_props, soft_reset, 1); | ||
761 | tuner_i2c_xfer_recv(&i2c_props, buf, PROBE_BUFFER_SIZE); | ||
762 | for (i = 1; i < PROBE_BUFFER_SIZE; i++) { | ||
763 | if (buf[i] != buf[0]) | ||
764 | break; | ||
765 | } | ||
766 | |||
767 | /* all bytes are equal, not a tda829x - probably a tda9887 */ | ||
768 | if (i == PROBE_BUFFER_SIZE) | ||
769 | return -ENODEV; | ||
770 | |||
771 | if ((tda8290_probe(&i2c_props) == 0) || | ||
772 | (tda8295_probe(&i2c_props) == 0)) | ||
773 | return 0; | ||
774 | |||
775 | /* fall back to old probing method */ | ||
776 | tuner_i2c_xfer_send(&i2c_props, easy_mode_b, 2); | ||
777 | tuner_i2c_xfer_send(&i2c_props, soft_reset, 2); | ||
778 | tuner_i2c_xfer_send(&i2c_props, &addr_dto_lsb, 1); | ||
779 | tuner_i2c_xfer_recv(&i2c_props, &data, 1); | ||
780 | if (data == 0) { | ||
781 | tuner_i2c_xfer_send(&i2c_props, easy_mode_g, 2); | ||
782 | tuner_i2c_xfer_send(&i2c_props, soft_reset, 2); | ||
783 | tuner_i2c_xfer_send(&i2c_props, &addr_dto_lsb, 1); | ||
784 | tuner_i2c_xfer_recv(&i2c_props, &data, 1); | ||
785 | if (data == 0x7b) { | ||
786 | return 0; | ||
787 | } | ||
788 | } | ||
789 | tuner_i2c_xfer_send(&i2c_props, restore_9886, 3); | ||
790 | return -ENODEV; | ||
791 | } | ||
792 | EXPORT_SYMBOL_GPL(tda829x_probe); | ||
793 | |||
794 | MODULE_DESCRIPTION("Philips/NXP TDA8290/TDA8295 analog IF demodulator driver"); | ||
795 | MODULE_AUTHOR("Gerd Knorr, Hartmut Hackmann, Michael Krufky"); | ||
796 | MODULE_LICENSE("GPL"); | ||
797 | |||
798 | /* | ||
799 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
800 | * --------------------------------------------------------------------------- | ||
801 | * Local variables: | ||
802 | * c-basic-offset: 8 | ||
803 | * End: | ||
804 | */ | ||