diff options
Diffstat (limited to 'drivers/media/video/mt20xx.c')
-rw-r--r-- | drivers/media/video/mt20xx.c | 246 |
1 files changed, 168 insertions, 78 deletions
diff --git a/drivers/media/video/mt20xx.c b/drivers/media/video/mt20xx.c index 41bc91817a16..f49d1f4c40db 100644 --- a/drivers/media/video/mt20xx.c +++ b/drivers/media/video/mt20xx.c | |||
@@ -1,12 +1,20 @@ | |||
1 | /* | 1 | /* |
2 | * | ||
3 | * i2c tv tuner chip device driver | 2 | * i2c tv tuner chip device driver |
4 | * controls microtune tuners, mt2032 + mt2050 at the moment. | 3 | * controls microtune tuners, mt2032 + mt2050 at the moment. |
4 | * | ||
5 | * This "mt20xx" module was split apart from the original "tuner" module. | ||
5 | */ | 6 | */ |
6 | #include <linux/delay.h> | 7 | #include <linux/delay.h> |
7 | #include <linux/i2c.h> | 8 | #include <linux/i2c.h> |
8 | #include <linux/videodev.h> | 9 | #include <linux/videodev.h> |
9 | #include "tuner-driver.h" | 10 | #include "tuner-i2c.h" |
11 | #include "mt20xx.h" | ||
12 | |||
13 | static int debug = 0; | ||
14 | module_param(debug, int, 0644); | ||
15 | MODULE_PARM_DESC(debug, "enable verbose debug messages"); | ||
16 | |||
17 | #define PREFIX "mt20xx " | ||
10 | 18 | ||
11 | /* ---------------------------------------------------------------------- */ | 19 | /* ---------------------------------------------------------------------- */ |
12 | 20 | ||
@@ -19,9 +27,6 @@ module_param(tv_antenna, int, 0644); | |||
19 | static unsigned int radio_antenna = 0; | 27 | static unsigned int radio_antenna = 0; |
20 | module_param(radio_antenna, int, 0644); | 28 | module_param(radio_antenna, int, 0644); |
21 | 29 | ||
22 | /* from tuner-core.c */ | ||
23 | extern int tuner_debug; | ||
24 | |||
25 | /* ---------------------------------------------------------------------- */ | 30 | /* ---------------------------------------------------------------------- */ |
26 | 31 | ||
27 | #define MT2032 0x04 | 32 | #define MT2032 0x04 |
@@ -40,19 +45,31 @@ struct microtune_priv { | |||
40 | struct tuner_i2c_props i2c_props; | 45 | struct tuner_i2c_props i2c_props; |
41 | 46 | ||
42 | unsigned int xogc; | 47 | unsigned int xogc; |
43 | unsigned int radio_if2; | 48 | //unsigned int radio_if2; |
49 | |||
50 | u32 frequency; | ||
44 | }; | 51 | }; |
45 | 52 | ||
46 | static void microtune_release(struct tuner *t) | 53 | static int microtune_release(struct dvb_frontend *fe) |
54 | { | ||
55 | kfree(fe->tuner_priv); | ||
56 | fe->tuner_priv = NULL; | ||
57 | |||
58 | return 0; | ||
59 | } | ||
60 | |||
61 | static int microtune_get_frequency(struct dvb_frontend *fe, u32 *frequency) | ||
47 | { | 62 | { |
48 | kfree(t->priv); | 63 | struct microtune_priv *priv = fe->tuner_priv; |
49 | t->priv = NULL; | 64 | *frequency = priv->frequency; |
65 | return 0; | ||
50 | } | 66 | } |
51 | 67 | ||
52 | // IsSpurInBand()? | 68 | // IsSpurInBand()? |
53 | static int mt2032_spurcheck(struct tuner *t, | 69 | static int mt2032_spurcheck(struct dvb_frontend *fe, |
54 | int f1, int f2, int spectrum_from,int spectrum_to) | 70 | int f1, int f2, int spectrum_from,int spectrum_to) |
55 | { | 71 | { |
72 | struct microtune_priv *priv = fe->tuner_priv; | ||
56 | int n1=1,n2,f; | 73 | int n1=1,n2,f; |
57 | 74 | ||
58 | f1=f1/1000; //scale to kHz to avoid 32bit overflows | 75 | f1=f1/1000; //scale to kHz to avoid 32bit overflows |
@@ -80,7 +97,7 @@ static int mt2032_spurcheck(struct tuner *t, | |||
80 | return 1; | 97 | return 1; |
81 | } | 98 | } |
82 | 99 | ||
83 | static int mt2032_compute_freq(struct tuner *t, | 100 | static int mt2032_compute_freq(struct dvb_frontend *fe, |
84 | unsigned int rfin, | 101 | unsigned int rfin, |
85 | unsigned int if1, unsigned int if2, | 102 | unsigned int if1, unsigned int if2, |
86 | unsigned int spectrum_from, | 103 | unsigned int spectrum_from, |
@@ -89,6 +106,7 @@ static int mt2032_compute_freq(struct tuner *t, | |||
89 | int *ret_sel, | 106 | int *ret_sel, |
90 | unsigned int xogc) //all in Hz | 107 | unsigned int xogc) //all in Hz |
91 | { | 108 | { |
109 | struct microtune_priv *priv = fe->tuner_priv; | ||
92 | unsigned int fref,lo1,lo1n,lo1a,s,sel,lo1freq, desired_lo1, | 110 | unsigned int fref,lo1,lo1n,lo1a,s,sel,lo1freq, desired_lo1, |
93 | desired_lo2,lo2,lo2n,lo2a,lo2num,lo2freq; | 111 | desired_lo2,lo2,lo2n,lo2a,lo2num,lo2freq; |
94 | 112 | ||
@@ -138,7 +156,7 @@ static int mt2032_compute_freq(struct tuner *t, | |||
138 | return(-1); | 156 | return(-1); |
139 | } | 157 | } |
140 | 158 | ||
141 | mt2032_spurcheck(t, lo1freq, desired_lo2, spectrum_from, spectrum_to); | 159 | mt2032_spurcheck(fe, lo1freq, desired_lo2, spectrum_from, spectrum_to); |
142 | // should recalculate lo1 (one step up/down) | 160 | // should recalculate lo1 (one step up/down) |
143 | 161 | ||
144 | // set up MT2032 register map for transfer over i2c | 162 | // set up MT2032 register map for transfer over i2c |
@@ -162,9 +180,9 @@ static int mt2032_compute_freq(struct tuner *t, | |||
162 | return 0; | 180 | return 0; |
163 | } | 181 | } |
164 | 182 | ||
165 | static int mt2032_check_lo_lock(struct tuner *t) | 183 | static int mt2032_check_lo_lock(struct dvb_frontend *fe) |
166 | { | 184 | { |
167 | struct microtune_priv *priv = t->priv; | 185 | struct microtune_priv *priv = fe->tuner_priv; |
168 | int try,lock=0; | 186 | int try,lock=0; |
169 | unsigned char buf[2]; | 187 | unsigned char buf[2]; |
170 | 188 | ||
@@ -184,9 +202,9 @@ static int mt2032_check_lo_lock(struct tuner *t) | |||
184 | return lock; | 202 | return lock; |
185 | } | 203 | } |
186 | 204 | ||
187 | static int mt2032_optimize_vco(struct tuner *t,int sel,int lock) | 205 | static int mt2032_optimize_vco(struct dvb_frontend *fe,int sel,int lock) |
188 | { | 206 | { |
189 | struct microtune_priv *priv = t->priv; | 207 | struct microtune_priv *priv = fe->tuner_priv; |
190 | unsigned char buf[2]; | 208 | unsigned char buf[2]; |
191 | int tad1; | 209 | int tad1; |
192 | 210 | ||
@@ -216,18 +234,18 @@ static int mt2032_optimize_vco(struct tuner *t,int sel,int lock) | |||
216 | buf[0]=0x0f; | 234 | buf[0]=0x0f; |
217 | buf[1]=sel; | 235 | buf[1]=sel; |
218 | tuner_i2c_xfer_send(&priv->i2c_props,buf,2); | 236 | tuner_i2c_xfer_send(&priv->i2c_props,buf,2); |
219 | lock=mt2032_check_lo_lock(t); | 237 | lock=mt2032_check_lo_lock(fe); |
220 | return lock; | 238 | return lock; |
221 | } | 239 | } |
222 | 240 | ||
223 | 241 | ||
224 | static void mt2032_set_if_freq(struct tuner *t, unsigned int rfin, | 242 | static void mt2032_set_if_freq(struct dvb_frontend *fe, unsigned int rfin, |
225 | unsigned int if1, unsigned int if2, | 243 | unsigned int if1, unsigned int if2, |
226 | unsigned int from, unsigned int to) | 244 | unsigned int from, unsigned int to) |
227 | { | 245 | { |
228 | unsigned char buf[21]; | 246 | unsigned char buf[21]; |
229 | int lint_try,ret,sel,lock=0; | 247 | int lint_try,ret,sel,lock=0; |
230 | struct microtune_priv *priv = t->priv; | 248 | struct microtune_priv *priv = fe->tuner_priv; |
231 | 249 | ||
232 | tuner_dbg("mt2032_set_if_freq rfin=%d if1=%d if2=%d from=%d to=%d\n", | 250 | tuner_dbg("mt2032_set_if_freq rfin=%d if1=%d if2=%d from=%d to=%d\n", |
233 | rfin,if1,if2,from,to); | 251 | rfin,if1,if2,from,to); |
@@ -237,7 +255,7 @@ static void mt2032_set_if_freq(struct tuner *t, unsigned int rfin, | |||
237 | tuner_i2c_xfer_recv(&priv->i2c_props,buf,21); | 255 | tuner_i2c_xfer_recv(&priv->i2c_props,buf,21); |
238 | 256 | ||
239 | buf[0]=0; | 257 | buf[0]=0; |
240 | ret=mt2032_compute_freq(t,rfin,if1,if2,from,to,&buf[1],&sel,priv->xogc); | 258 | ret=mt2032_compute_freq(fe,rfin,if1,if2,from,to,&buf[1],&sel,priv->xogc); |
241 | if (ret<0) | 259 | if (ret<0) |
242 | return; | 260 | return; |
243 | 261 | ||
@@ -253,10 +271,10 @@ static void mt2032_set_if_freq(struct tuner *t, unsigned int rfin, | |||
253 | 271 | ||
254 | // wait for PLLs to lock (per manual), retry LINT if not. | 272 | // wait for PLLs to lock (per manual), retry LINT if not. |
255 | for(lint_try=0; lint_try<2; lint_try++) { | 273 | for(lint_try=0; lint_try<2; lint_try++) { |
256 | lock=mt2032_check_lo_lock(t); | 274 | lock=mt2032_check_lo_lock(fe); |
257 | 275 | ||
258 | if(optimize_vco) | 276 | if(optimize_vco) |
259 | lock=mt2032_optimize_vco(t,sel,lock); | 277 | lock=mt2032_optimize_vco(fe,sel,lock); |
260 | if(lock==6) break; | 278 | if(lock==6) break; |
261 | 279 | ||
262 | tuner_dbg("mt2032: re-init PLLs by LINT\n"); | 280 | tuner_dbg("mt2032: re-init PLLs by LINT\n"); |
@@ -279,12 +297,13 @@ static void mt2032_set_if_freq(struct tuner *t, unsigned int rfin, | |||
279 | } | 297 | } |
280 | 298 | ||
281 | 299 | ||
282 | static void mt2032_set_tv_freq(struct tuner *t, unsigned int freq) | 300 | static int mt2032_set_tv_freq(struct dvb_frontend *fe, |
301 | struct analog_parameters *params) | ||
283 | { | 302 | { |
284 | int if2,from,to; | 303 | int if2,from,to; |
285 | 304 | ||
286 | // signal bandwidth and picture carrier | 305 | // signal bandwidth and picture carrier |
287 | if (t->std & V4L2_STD_525_60) { | 306 | if (params->std & V4L2_STD_525_60) { |
288 | // NTSC | 307 | // NTSC |
289 | from = 40750*1000; | 308 | from = 40750*1000; |
290 | to = 46750*1000; | 309 | to = 46750*1000; |
@@ -296,30 +315,64 @@ static void mt2032_set_tv_freq(struct tuner *t, unsigned int freq) | |||
296 | if2 = 38900*1000; | 315 | if2 = 38900*1000; |
297 | } | 316 | } |
298 | 317 | ||
299 | mt2032_set_if_freq(t, freq*62500 /* freq*1000*1000/16 */, | 318 | mt2032_set_if_freq(fe, params->frequency*62500, |
300 | 1090*1000*1000, if2, from, to); | 319 | 1090*1000*1000, if2, from, to); |
320 | |||
321 | return 0; | ||
301 | } | 322 | } |
302 | 323 | ||
303 | static void mt2032_set_radio_freq(struct tuner *t, unsigned int freq) | 324 | static int mt2032_set_radio_freq(struct dvb_frontend *fe, |
325 | struct analog_parameters *params) | ||
304 | { | 326 | { |
305 | struct microtune_priv *priv = t->priv; | 327 | struct microtune_priv *priv = fe->tuner_priv; |
306 | int if2 = priv->radio_if2; | 328 | int if2; |
329 | |||
330 | if (params->std & V4L2_STD_525_60) { | ||
331 | tuner_dbg("pinnacle ntsc\n"); | ||
332 | if2 = 41300 * 1000; | ||
333 | } else { | ||
334 | tuner_dbg("pinnacle pal\n"); | ||
335 | if2 = 33300 * 1000; | ||
336 | } | ||
307 | 337 | ||
308 | // per Manual for FM tuning: first if center freq. 1085 MHz | 338 | // per Manual for FM tuning: first if center freq. 1085 MHz |
309 | mt2032_set_if_freq(t, freq * 1000 / 16, | 339 | mt2032_set_if_freq(fe, params->frequency * 125 / 2, |
310 | 1085*1000*1000,if2,if2,if2); | 340 | 1085*1000*1000,if2,if2,if2); |
341 | |||
342 | return 0; | ||
311 | } | 343 | } |
312 | 344 | ||
313 | static struct tuner_operations mt2032_tuner_ops = { | 345 | static int mt2032_set_params(struct dvb_frontend *fe, |
314 | .set_tv_freq = mt2032_set_tv_freq, | 346 | struct analog_parameters *params) |
315 | .set_radio_freq = mt2032_set_radio_freq, | 347 | { |
316 | .release = microtune_release, | 348 | struct microtune_priv *priv = fe->tuner_priv; |
349 | int ret = -EINVAL; | ||
350 | |||
351 | switch (params->mode) { | ||
352 | case V4L2_TUNER_RADIO: | ||
353 | ret = mt2032_set_radio_freq(fe, params); | ||
354 | priv->frequency = params->frequency * 125 / 2; | ||
355 | break; | ||
356 | case V4L2_TUNER_ANALOG_TV: | ||
357 | case V4L2_TUNER_DIGITAL_TV: | ||
358 | ret = mt2032_set_tv_freq(fe, params); | ||
359 | priv->frequency = params->frequency * 62500; | ||
360 | break; | ||
361 | } | ||
362 | |||
363 | return ret; | ||
364 | } | ||
365 | |||
366 | static struct dvb_tuner_ops mt2032_tuner_ops = { | ||
367 | .set_analog_params = mt2032_set_params, | ||
368 | .release = microtune_release, | ||
369 | .get_frequency = microtune_get_frequency, | ||
317 | }; | 370 | }; |
318 | 371 | ||
319 | // Initalization as described in "MT203x Programming Procedures", Rev 1.2, Feb.2001 | 372 | // Initalization as described in "MT203x Programming Procedures", Rev 1.2, Feb.2001 |
320 | static int mt2032_init(struct tuner *t) | 373 | static int mt2032_init(struct dvb_frontend *fe) |
321 | { | 374 | { |
322 | struct microtune_priv *priv = t->priv; | 375 | struct microtune_priv *priv = fe->tuner_priv; |
323 | unsigned char buf[21]; | 376 | unsigned char buf[21]; |
324 | int ret,xogc,xok=0; | 377 | int ret,xogc,xok=0; |
325 | 378 | ||
@@ -368,14 +421,14 @@ static int mt2032_init(struct tuner *t) | |||
368 | } while (xok != 1 ); | 421 | } while (xok != 1 ); |
369 | priv->xogc=xogc; | 422 | priv->xogc=xogc; |
370 | 423 | ||
371 | memcpy(&t->ops, &mt2032_tuner_ops, sizeof(struct tuner_operations)); | 424 | memcpy(&fe->ops.tuner_ops, &mt2032_tuner_ops, sizeof(struct dvb_tuner_ops)); |
372 | 425 | ||
373 | return(1); | 426 | return(1); |
374 | } | 427 | } |
375 | 428 | ||
376 | static void mt2050_set_antenna(struct tuner *t, unsigned char antenna) | 429 | static void mt2050_set_antenna(struct dvb_frontend *fe, unsigned char antenna) |
377 | { | 430 | { |
378 | struct microtune_priv *priv = t->priv; | 431 | struct microtune_priv *priv = fe->tuner_priv; |
379 | unsigned char buf[2]; | 432 | unsigned char buf[2]; |
380 | int ret; | 433 | int ret; |
381 | 434 | ||
@@ -385,9 +438,9 @@ static void mt2050_set_antenna(struct tuner *t, unsigned char antenna) | |||
385 | tuner_dbg("mt2050: enabled antenna connector %d\n", antenna); | 438 | tuner_dbg("mt2050: enabled antenna connector %d\n", antenna); |
386 | } | 439 | } |
387 | 440 | ||
388 | static void mt2050_set_if_freq(struct tuner *t,unsigned int freq, unsigned int if2) | 441 | static void mt2050_set_if_freq(struct dvb_frontend *fe,unsigned int freq, unsigned int if2) |
389 | { | 442 | { |
390 | struct microtune_priv *priv = t->priv; | 443 | struct microtune_priv *priv = fe->tuner_priv; |
391 | unsigned int if1=1218*1000*1000; | 444 | unsigned int if1=1218*1000*1000; |
392 | unsigned int f_lo1,f_lo2,lo1,lo2,f_lo1_modulo,f_lo2_modulo,num1,num2,div1a,div1b,div2a,div2b; | 445 | unsigned int f_lo1,f_lo2,lo1,lo2,f_lo1_modulo,f_lo2_modulo,num1,num2,div1a,div1b,div2a,div2b; |
393 | int ret; | 446 | int ret; |
@@ -419,7 +472,7 @@ static void mt2050_set_if_freq(struct tuner *t,unsigned int freq, unsigned int i | |||
419 | div2a=(lo2/8)-1; | 472 | div2a=(lo2/8)-1; |
420 | div2b=lo2-(div2a+1)*8; | 473 | div2b=lo2-(div2a+1)*8; |
421 | 474 | ||
422 | if (tuner_debug > 1) { | 475 | if (debug > 1) { |
423 | tuner_dbg("lo1 lo2 = %d %d\n", lo1, lo2); | 476 | tuner_dbg("lo1 lo2 = %d %d\n", lo1, lo2); |
424 | tuner_dbg("num1 num2 div1a div1b div2a div2b= %x %x %x %x %x %x\n", | 477 | tuner_dbg("num1 num2 div1a div1b div2a div2b= %x %x %x %x %x %x\n", |
425 | num1,num2,div1a,div1b,div2a,div2b); | 478 | num1,num2,div1a,div1b,div2a,div2b); |
@@ -435,7 +488,7 @@ static void mt2050_set_if_freq(struct tuner *t,unsigned int freq, unsigned int i | |||
435 | buf[5]=div2a; | 488 | buf[5]=div2a; |
436 | if(num2!=0) buf[5]=buf[5]|0x40; | 489 | if(num2!=0) buf[5]=buf[5]|0x40; |
437 | 490 | ||
438 | if (tuner_debug > 1) { | 491 | if (debug > 1) { |
439 | int i; | 492 | int i; |
440 | tuner_dbg("bufs is: "); | 493 | tuner_dbg("bufs is: "); |
441 | for(i=0;i<6;i++) | 494 | for(i=0;i<6;i++) |
@@ -448,43 +501,78 @@ static void mt2050_set_if_freq(struct tuner *t,unsigned int freq, unsigned int i | |||
448 | tuner_warn("i2c i/o error: rc == %d (should be 6)\n",ret); | 501 | tuner_warn("i2c i/o error: rc == %d (should be 6)\n",ret); |
449 | } | 502 | } |
450 | 503 | ||
451 | static void mt2050_set_tv_freq(struct tuner *t, unsigned int freq) | 504 | static int mt2050_set_tv_freq(struct dvb_frontend *fe, |
505 | struct analog_parameters *params) | ||
452 | { | 506 | { |
453 | unsigned int if2; | 507 | unsigned int if2; |
454 | 508 | ||
455 | if (t->std & V4L2_STD_525_60) { | 509 | if (params->std & V4L2_STD_525_60) { |
456 | // NTSC | 510 | // NTSC |
457 | if2 = 45750*1000; | 511 | if2 = 45750*1000; |
458 | } else { | 512 | } else { |
459 | // PAL | 513 | // PAL |
460 | if2 = 38900*1000; | 514 | if2 = 38900*1000; |
461 | } | 515 | } |
462 | if (V4L2_TUNER_DIGITAL_TV == t->mode) { | 516 | if (V4L2_TUNER_DIGITAL_TV == params->mode) { |
463 | // DVB (pinnacle 300i) | 517 | // DVB (pinnacle 300i) |
464 | if2 = 36150*1000; | 518 | if2 = 36150*1000; |
465 | } | 519 | } |
466 | mt2050_set_if_freq(t, freq*62500, if2); | 520 | mt2050_set_if_freq(fe, params->frequency*62500, if2); |
467 | mt2050_set_antenna(t, tv_antenna); | 521 | mt2050_set_antenna(fe, tv_antenna); |
522 | |||
523 | return 0; | ||
524 | } | ||
525 | |||
526 | static int mt2050_set_radio_freq(struct dvb_frontend *fe, | ||
527 | struct analog_parameters *params) | ||
528 | { | ||
529 | struct microtune_priv *priv = fe->tuner_priv; | ||
530 | int if2; | ||
531 | |||
532 | if (params->std & V4L2_STD_525_60) { | ||
533 | tuner_dbg("pinnacle ntsc\n"); | ||
534 | if2 = 41300 * 1000; | ||
535 | } else { | ||
536 | tuner_dbg("pinnacle pal\n"); | ||
537 | if2 = 33300 * 1000; | ||
538 | } | ||
539 | |||
540 | mt2050_set_if_freq(fe, params->frequency * 125 / 2, if2); | ||
541 | mt2050_set_antenna(fe, radio_antenna); | ||
542 | |||
543 | return 0; | ||
468 | } | 544 | } |
469 | 545 | ||
470 | static void mt2050_set_radio_freq(struct tuner *t, unsigned int freq) | 546 | static int mt2050_set_params(struct dvb_frontend *fe, |
547 | struct analog_parameters *params) | ||
471 | { | 548 | { |
472 | struct microtune_priv *priv = t->priv; | 549 | struct microtune_priv *priv = fe->tuner_priv; |
473 | int if2 = priv->radio_if2; | 550 | int ret = -EINVAL; |
474 | 551 | ||
475 | mt2050_set_if_freq(t, freq * 1000 / 16, if2); | 552 | switch (params->mode) { |
476 | mt2050_set_antenna(t, radio_antenna); | 553 | case V4L2_TUNER_RADIO: |
554 | ret = mt2050_set_radio_freq(fe, params); | ||
555 | priv->frequency = params->frequency * 125 / 2; | ||
556 | break; | ||
557 | case V4L2_TUNER_ANALOG_TV: | ||
558 | case V4L2_TUNER_DIGITAL_TV: | ||
559 | ret = mt2050_set_tv_freq(fe, params); | ||
560 | priv->frequency = params->frequency * 62500; | ||
561 | break; | ||
562 | } | ||
563 | |||
564 | return ret; | ||
477 | } | 565 | } |
478 | 566 | ||
479 | static struct tuner_operations mt2050_tuner_ops = { | 567 | static struct dvb_tuner_ops mt2050_tuner_ops = { |
480 | .set_tv_freq = mt2050_set_tv_freq, | 568 | .set_analog_params = mt2050_set_params, |
481 | .set_radio_freq = mt2050_set_radio_freq, | 569 | .release = microtune_release, |
482 | .release = microtune_release, | 570 | .get_frequency = microtune_get_frequency, |
483 | }; | 571 | }; |
484 | 572 | ||
485 | static int mt2050_init(struct tuner *t) | 573 | static int mt2050_init(struct dvb_frontend *fe) |
486 | { | 574 | { |
487 | struct microtune_priv *priv = t->priv; | 575 | struct microtune_priv *priv = fe->tuner_priv; |
488 | unsigned char buf[2]; | 576 | unsigned char buf[2]; |
489 | int ret; | 577 | int ret; |
490 | 578 | ||
@@ -502,12 +590,14 @@ static int mt2050_init(struct tuner *t) | |||
502 | 590 | ||
503 | tuner_dbg("mt2050: sro is %x\n",buf[0]); | 591 | tuner_dbg("mt2050: sro is %x\n",buf[0]); |
504 | 592 | ||
505 | memcpy(&t->ops, &mt2050_tuner_ops, sizeof(struct tuner_operations)); | 593 | memcpy(&fe->ops.tuner_ops, &mt2050_tuner_ops, sizeof(struct dvb_tuner_ops)); |
506 | 594 | ||
507 | return 0; | 595 | return 0; |
508 | } | 596 | } |
509 | 597 | ||
510 | int microtune_init(struct tuner *t) | 598 | struct dvb_frontend *microtune_attach(struct dvb_frontend *fe, |
599 | struct i2c_adapter* i2c_adap, | ||
600 | u8 i2c_addr) | ||
511 | { | 601 | { |
512 | struct microtune_priv *priv = NULL; | 602 | struct microtune_priv *priv = NULL; |
513 | char *name; | 603 | char *name; |
@@ -516,28 +606,21 @@ int microtune_init(struct tuner *t) | |||
516 | 606 | ||
517 | priv = kzalloc(sizeof(struct microtune_priv), GFP_KERNEL); | 607 | priv = kzalloc(sizeof(struct microtune_priv), GFP_KERNEL); |
518 | if (priv == NULL) | 608 | if (priv == NULL) |
519 | return -ENOMEM; | 609 | return NULL; |
520 | t->priv = priv; | 610 | fe->tuner_priv = priv; |
521 | 611 | ||
522 | priv->i2c_props.addr = t->i2c.addr; | 612 | priv->i2c_props.addr = i2c_addr; |
523 | priv->i2c_props.adap = t->i2c.adapter; | 613 | priv->i2c_props.adap = i2c_adap; |
524 | 614 | ||
525 | priv->radio_if2 = 10700 * 1000; /* 10.7MHz - FM radio */ | 615 | //priv->radio_if2 = 10700 * 1000; /* 10.7MHz - FM radio */ |
526 | 616 | ||
527 | memset(buf,0,sizeof(buf)); | 617 | memset(buf,0,sizeof(buf)); |
528 | 618 | ||
529 | if (t->std & V4L2_STD_525_60) { | ||
530 | tuner_dbg("pinnacle ntsc\n"); | ||
531 | priv->radio_if2 = 41300 * 1000; | ||
532 | } else { | ||
533 | tuner_dbg("pinnacle pal\n"); | ||
534 | priv->radio_if2 = 33300 * 1000; | ||
535 | } | ||
536 | name = "unknown"; | 619 | name = "unknown"; |
537 | 620 | ||
538 | tuner_i2c_xfer_send(&priv->i2c_props,buf,1); | 621 | tuner_i2c_xfer_send(&priv->i2c_props,buf,1); |
539 | tuner_i2c_xfer_recv(&priv->i2c_props,buf,21); | 622 | tuner_i2c_xfer_recv(&priv->i2c_props,buf,21); |
540 | if (tuner_debug) { | 623 | if (debug) { |
541 | int i; | 624 | int i; |
542 | tuner_dbg("MT20xx hexdump:"); | 625 | tuner_dbg("MT20xx hexdump:"); |
543 | for(i=0;i<21;i++) { | 626 | for(i=0;i<21;i++) { |
@@ -556,10 +639,10 @@ int microtune_init(struct tuner *t) | |||
556 | name = microtune_part[buf[0x13]]; | 639 | name = microtune_part[buf[0x13]]; |
557 | switch (buf[0x13]) { | 640 | switch (buf[0x13]) { |
558 | case MT2032: | 641 | case MT2032: |
559 | mt2032_init(t); | 642 | mt2032_init(fe); |
560 | break; | 643 | break; |
561 | case MT2050: | 644 | case MT2050: |
562 | mt2050_init(t); | 645 | mt2050_init(fe); |
563 | break; | 646 | break; |
564 | default: | 647 | default: |
565 | tuner_info("microtune %s found, not (yet?) supported, sorry :-/\n", | 648 | tuner_info("microtune %s found, not (yet?) supported, sorry :-/\n", |
@@ -567,11 +650,18 @@ int microtune_init(struct tuner *t) | |||
567 | return 0; | 650 | return 0; |
568 | } | 651 | } |
569 | 652 | ||
570 | strlcpy(t->i2c.name, name, sizeof(t->i2c.name)); | 653 | strlcpy(fe->ops.tuner_ops.info.name, name, |
654 | sizeof(fe->ops.tuner_ops.info.name)); | ||
571 | tuner_info("microtune %s found, OK\n",name); | 655 | tuner_info("microtune %s found, OK\n",name); |
572 | return 0; | 656 | return fe; |
573 | } | 657 | } |
574 | 658 | ||
659 | EXPORT_SYMBOL_GPL(microtune_attach); | ||
660 | |||
661 | MODULE_DESCRIPTION("Microtune tuner driver"); | ||
662 | MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer"); | ||
663 | MODULE_LICENSE("GPL"); | ||
664 | |||
575 | /* | 665 | /* |
576 | * Overrides for Emacs so that we follow Linus's tabbing style. | 666 | * Overrides for Emacs so that we follow Linus's tabbing style. |
577 | * --------------------------------------------------------------------------- | 667 | * --------------------------------------------------------------------------- |