V4L/DVB (5734): Cx88: kill dev->fw_size
[linux-2.6] / drivers / media / video / mt20xx.c
1 /*
2  *
3  * i2c tv tuner chip device driver
4  * controls microtune tuners, mt2032 + mt2050 at the moment.
5  */
6 #include <linux/delay.h>
7 #include <linux/i2c.h>
8 #include <linux/videodev.h>
9 #include <linux/moduleparam.h>
10 #include <media/tuner.h>
11
12 /* ---------------------------------------------------------------------- */
13
14 static unsigned int optimize_vco  = 1;
15 module_param(optimize_vco,      int, 0644);
16
17 static unsigned int tv_antenna    = 1;
18 module_param(tv_antenna,        int, 0644);
19
20 static unsigned int radio_antenna = 0;
21 module_param(radio_antenna,     int, 0644);
22
23 /* from tuner-core.c */
24 extern int tuner_debug;
25
26 /* ---------------------------------------------------------------------- */
27
28 #define MT2032 0x04
29 #define MT2030 0x06
30 #define MT2040 0x07
31 #define MT2050 0x42
32
33 static char *microtune_part[] = {
34         [ MT2030 ] = "MT2030",
35         [ MT2032 ] = "MT2032",
36         [ MT2040 ] = "MT2040",
37         [ MT2050 ] = "MT2050",
38 };
39
40 struct microtune_priv {
41         unsigned int xogc;
42         unsigned int radio_if2;
43 };
44
45 // IsSpurInBand()?
46 static int mt2032_spurcheck(struct i2c_client *c,
47                             int f1, int f2, int spectrum_from,int spectrum_to)
48 {
49         struct tuner *t = i2c_get_clientdata(c);
50         int n1=1,n2,f;
51
52         f1=f1/1000; //scale to kHz to avoid 32bit overflows
53         f2=f2/1000;
54         spectrum_from/=1000;
55         spectrum_to/=1000;
56
57         tuner_dbg("spurcheck f1=%d f2=%d  from=%d to=%d\n",
58                   f1,f2,spectrum_from,spectrum_to);
59
60         do {
61             n2=-n1;
62             f=n1*(f1-f2);
63             do {
64                 n2--;
65                 f=f-f2;
66                 tuner_dbg("spurtest n1=%d n2=%d ftest=%d\n",n1,n2,f);
67
68                 if( (f>spectrum_from) && (f<spectrum_to))
69                         tuner_dbg("mt2032 spurcheck triggered: %d\n",n1);
70             } while ( (f>(f2-spectrum_to)) || (n2>-5));
71             n1++;
72         } while (n1<5);
73
74         return 1;
75 }
76
77 static int mt2032_compute_freq(struct i2c_client *c,
78                                unsigned int rfin,
79                                unsigned int if1, unsigned int if2,
80                                unsigned int spectrum_from,
81                                unsigned int spectrum_to,
82                                unsigned char *buf,
83                                int *ret_sel,
84                                unsigned int xogc) //all in Hz
85 {
86         struct tuner *t = i2c_get_clientdata(c);
87         unsigned int fref,lo1,lo1n,lo1a,s,sel,lo1freq, desired_lo1,
88                 desired_lo2,lo2,lo2n,lo2a,lo2num,lo2freq;
89
90         fref= 5250 *1000; //5.25MHz
91         desired_lo1=rfin+if1;
92
93         lo1=(2*(desired_lo1/1000)+(fref/1000)) / (2*fref/1000);
94         lo1n=lo1/8;
95         lo1a=lo1-(lo1n*8);
96
97         s=rfin/1000/1000+1090;
98
99         if(optimize_vco) {
100                 if(s>1890) sel=0;
101                 else if(s>1720) sel=1;
102                 else if(s>1530) sel=2;
103                 else if(s>1370) sel=3;
104                 else sel=4; // >1090
105         }
106         else {
107                 if(s>1790) sel=0; // <1958
108                 else if(s>1617) sel=1;
109                 else if(s>1449) sel=2;
110                 else if(s>1291) sel=3;
111                 else sel=4; // >1090
112         }
113         *ret_sel=sel;
114
115         lo1freq=(lo1a+8*lo1n)*fref;
116
117         tuner_dbg("mt2032: rfin=%d lo1=%d lo1n=%d lo1a=%d sel=%d, lo1freq=%d\n",
118                   rfin,lo1,lo1n,lo1a,sel,lo1freq);
119
120         desired_lo2=lo1freq-rfin-if2;
121         lo2=(desired_lo2)/fref;
122         lo2n=lo2/8;
123         lo2a=lo2-(lo2n*8);
124         lo2num=((desired_lo2/1000)%(fref/1000))* 3780/(fref/1000); //scale to fit in 32bit arith
125         lo2freq=(lo2a+8*lo2n)*fref + lo2num*(fref/1000)/3780*1000;
126
127         tuner_dbg("mt2032: rfin=%d lo2=%d lo2n=%d lo2a=%d num=%d lo2freq=%d\n",
128                   rfin,lo2,lo2n,lo2a,lo2num,lo2freq);
129
130         if(lo1a<0 || lo1a>7 || lo1n<17 ||lo1n>48 || lo2a<0 ||lo2a >7 ||lo2n<17 || lo2n>30) {
131                 tuner_info("mt2032: frequency parameters out of range: %d %d %d %d\n",
132                            lo1a, lo1n, lo2a,lo2n);
133                 return(-1);
134         }
135
136         mt2032_spurcheck(c, lo1freq, desired_lo2,  spectrum_from, spectrum_to);
137         // should recalculate lo1 (one step up/down)
138
139         // set up MT2032 register map for transfer over i2c
140         buf[0]=lo1n-1;
141         buf[1]=lo1a | (sel<<4);
142         buf[2]=0x86; // LOGC
143         buf[3]=0x0f; //reserved
144         buf[4]=0x1f;
145         buf[5]=(lo2n-1) | (lo2a<<5);
146         if(rfin >400*1000*1000)
147                 buf[6]=0xe4;
148         else
149                 buf[6]=0xf4; // set PKEN per rev 1.2
150         buf[7]=8+xogc;
151         buf[8]=0xc3; //reserved
152         buf[9]=0x4e; //reserved
153         buf[10]=0xec; //reserved
154         buf[11]=(lo2num&0xff);
155         buf[12]=(lo2num>>8) |0x80; // Lo2RST
156
157         return 0;
158 }
159
160 static int mt2032_check_lo_lock(struct i2c_client *c)
161 {
162         struct tuner *t = i2c_get_clientdata(c);
163         int try,lock=0;
164         unsigned char buf[2];
165
166         for(try=0;try<10;try++) {
167                 buf[0]=0x0e;
168                 i2c_master_send(c,buf,1);
169                 i2c_master_recv(c,buf,1);
170                 tuner_dbg("mt2032 Reg.E=0x%02x\n",buf[0]);
171                 lock=buf[0] &0x06;
172
173                 if (lock==6)
174                         break;
175
176                 tuner_dbg("mt2032: pll wait 1ms for lock (0x%2x)\n",buf[0]);
177                 udelay(1000);
178         }
179         return lock;
180 }
181
182 static int mt2032_optimize_vco(struct i2c_client *c,int sel,int lock)
183 {
184         struct tuner *t = i2c_get_clientdata(c);
185         unsigned char buf[2];
186         int tad1;
187
188         buf[0]=0x0f;
189         i2c_master_send(c,buf,1);
190         i2c_master_recv(c,buf,1);
191         tuner_dbg("mt2032 Reg.F=0x%02x\n",buf[0]);
192         tad1=buf[0]&0x07;
193
194         if(tad1 ==0) return lock;
195         if(tad1 ==1) return lock;
196
197         if(tad1==2) {
198                 if(sel==0)
199                         return lock;
200                 else sel--;
201         }
202         else {
203                 if(sel<4)
204                         sel++;
205                 else
206                         return lock;
207         }
208
209         tuner_dbg("mt2032 optimize_vco: sel=%d\n",sel);
210
211         buf[0]=0x0f;
212         buf[1]=sel;
213         i2c_master_send(c,buf,2);
214         lock=mt2032_check_lo_lock(c);
215         return lock;
216 }
217
218
219 static void mt2032_set_if_freq(struct i2c_client *c, unsigned int rfin,
220                                unsigned int if1, unsigned int if2,
221                                unsigned int from, unsigned int to)
222 {
223         unsigned char buf[21];
224         int lint_try,ret,sel,lock=0;
225         struct tuner *t = i2c_get_clientdata(c);
226         struct microtune_priv *priv = t->priv;
227
228         tuner_dbg("mt2032_set_if_freq rfin=%d if1=%d if2=%d from=%d to=%d\n",
229                   rfin,if1,if2,from,to);
230
231         buf[0]=0;
232         ret=i2c_master_send(c,buf,1);
233         i2c_master_recv(c,buf,21);
234
235         buf[0]=0;
236         ret=mt2032_compute_freq(c,rfin,if1,if2,from,to,&buf[1],&sel,priv->xogc);
237         if (ret<0)
238                 return;
239
240         // send only the relevant registers per Rev. 1.2
241         buf[0]=0;
242         ret=i2c_master_send(c,buf,4);
243         buf[5]=5;
244         ret=i2c_master_send(c,buf+5,4);
245         buf[11]=11;
246         ret=i2c_master_send(c,buf+11,3);
247         if(ret!=3)
248                 tuner_warn("i2c i/o error: rc == %d (should be 3)\n",ret);
249
250         // wait for PLLs to lock (per manual), retry LINT if not.
251         for(lint_try=0; lint_try<2; lint_try++) {
252                 lock=mt2032_check_lo_lock(c);
253
254                 if(optimize_vco)
255                         lock=mt2032_optimize_vco(c,sel,lock);
256                 if(lock==6) break;
257
258                 tuner_dbg("mt2032: re-init PLLs by LINT\n");
259                 buf[0]=7;
260                 buf[1]=0x80 +8+priv->xogc; // set LINT to re-init PLLs
261                 i2c_master_send(c,buf,2);
262                 mdelay(10);
263                 buf[1]=8+priv->xogc;
264                 i2c_master_send(c,buf,2);
265         }
266
267         if (lock!=6)
268                 tuner_warn("MT2032 Fatal Error: PLLs didn't lock.\n");
269
270         buf[0]=2;
271         buf[1]=0x20; // LOGC for optimal phase noise
272         ret=i2c_master_send(c,buf,2);
273         if (ret!=2)
274                 tuner_warn("i2c i/o error: rc == %d (should be 2)\n",ret);
275 }
276
277
278 static void mt2032_set_tv_freq(struct i2c_client *c, unsigned int freq)
279 {
280         struct tuner *t = i2c_get_clientdata(c);
281         int if2,from,to;
282
283         // signal bandwidth and picture carrier
284         if (t->std & V4L2_STD_525_60) {
285                 // NTSC
286                 from = 40750*1000;
287                 to   = 46750*1000;
288                 if2  = 45750*1000;
289         } else {
290                 // PAL
291                 from = 32900*1000;
292                 to   = 39900*1000;
293                 if2  = 38900*1000;
294         }
295
296         mt2032_set_if_freq(c, freq*62500 /* freq*1000*1000/16 */,
297                            1090*1000*1000, if2, from, to);
298 }
299
300 static void mt2032_set_radio_freq(struct i2c_client *c, unsigned int freq)
301 {
302         struct tuner *t = i2c_get_clientdata(c);
303         struct microtune_priv *priv = t->priv;
304         int if2 = priv->radio_if2;
305
306         // per Manual for FM tuning: first if center freq. 1085 MHz
307         mt2032_set_if_freq(c, freq * 1000 / 16,
308                               1085*1000*1000,if2,if2,if2);
309 }
310
311 // Initalization as described in "MT203x Programming Procedures", Rev 1.2, Feb.2001
312 static int mt2032_init(struct i2c_client *c)
313 {
314         struct tuner *t = i2c_get_clientdata(c);
315         struct microtune_priv *priv = t->priv;
316         unsigned char buf[21];
317         int ret,xogc,xok=0;
318
319         // Initialize Registers per spec.
320         buf[1]=2; // Index to register 2
321         buf[2]=0xff;
322         buf[3]=0x0f;
323         buf[4]=0x1f;
324         ret=i2c_master_send(c,buf+1,4);
325
326         buf[5]=6; // Index register 6
327         buf[6]=0xe4;
328         buf[7]=0x8f;
329         buf[8]=0xc3;
330         buf[9]=0x4e;
331         buf[10]=0xec;
332         ret=i2c_master_send(c,buf+5,6);
333
334         buf[12]=13;  // Index register 13
335         buf[13]=0x32;
336         ret=i2c_master_send(c,buf+12,2);
337
338         // Adjust XOGC (register 7), wait for XOK
339         xogc=7;
340         do {
341                 tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07);
342                 mdelay(10);
343                 buf[0]=0x0e;
344                 i2c_master_send(c,buf,1);
345                 i2c_master_recv(c,buf,1);
346                 xok=buf[0]&0x01;
347                 tuner_dbg("mt2032: xok = 0x%02x\n",xok);
348                 if (xok == 1) break;
349
350                 xogc--;
351                 tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07);
352                 if (xogc == 3) {
353                         xogc=4; // min. 4 per spec
354                         break;
355                 }
356                 buf[0]=0x07;
357                 buf[1]=0x88 + xogc;
358                 ret=i2c_master_send(c,buf,2);
359                 if (ret!=2)
360                         tuner_warn("i2c i/o error: rc == %d (should be 2)\n",ret);
361         } while (xok != 1 );
362         priv->xogc=xogc;
363
364         t->set_tv_freq    = mt2032_set_tv_freq;
365         t->set_radio_freq = mt2032_set_radio_freq;
366         return(1);
367 }
368
369 static void mt2050_set_antenna(struct i2c_client *c, unsigned char antenna)
370 {
371         struct tuner *t = i2c_get_clientdata(c);
372         unsigned char buf[2];
373         int ret;
374
375         buf[0] = 6;
376         buf[1] = antenna ? 0x11 : 0x10;
377         ret=i2c_master_send(c,buf,2);
378         tuner_dbg("mt2050: enabled antenna connector %d\n", antenna);
379 }
380
381 static void mt2050_set_if_freq(struct i2c_client *c,unsigned int freq, unsigned int if2)
382 {
383         struct tuner *t = i2c_get_clientdata(c);
384         unsigned int if1=1218*1000*1000;
385         unsigned int f_lo1,f_lo2,lo1,lo2,f_lo1_modulo,f_lo2_modulo,num1,num2,div1a,div1b,div2a,div2b;
386         int ret;
387         unsigned char buf[6];
388
389         tuner_dbg("mt2050_set_if_freq freq=%d if1=%d if2=%d\n",
390                   freq,if1,if2);
391
392         f_lo1=freq+if1;
393         f_lo1=(f_lo1/1000000)*1000000;
394
395         f_lo2=f_lo1-freq-if2;
396         f_lo2=(f_lo2/50000)*50000;
397
398         lo1=f_lo1/4000000;
399         lo2=f_lo2/4000000;
400
401         f_lo1_modulo= f_lo1-(lo1*4000000);
402         f_lo2_modulo= f_lo2-(lo2*4000000);
403
404         num1=4*f_lo1_modulo/4000000;
405         num2=4096*(f_lo2_modulo/1000)/4000;
406
407         // todo spurchecks
408
409         div1a=(lo1/12)-1;
410         div1b=lo1-(div1a+1)*12;
411
412         div2a=(lo2/8)-1;
413         div2b=lo2-(div2a+1)*8;
414
415         if (tuner_debug > 1) {
416                 tuner_dbg("lo1 lo2 = %d %d\n", lo1, lo2);
417                 tuner_dbg("num1 num2 div1a div1b div2a div2b= %x %x %x %x %x %x\n",
418                           num1,num2,div1a,div1b,div2a,div2b);
419         }
420
421         buf[0]=1;
422         buf[1]= 4*div1b + num1;
423         if(freq<275*1000*1000) buf[1] = buf[1]|0x80;
424
425         buf[2]=div1a;
426         buf[3]=32*div2b + num2/256;
427         buf[4]=num2-(num2/256)*256;
428         buf[5]=div2a;
429         if(num2!=0) buf[5]=buf[5]|0x40;
430
431         if (tuner_debug > 1) {
432                 int i;
433                 tuner_dbg("bufs is: ");
434                 for(i=0;i<6;i++)
435                         printk("%x ",buf[i]);
436                 printk("\n");
437         }
438
439         ret=i2c_master_send(c,buf,6);
440         if (ret!=6)
441                 tuner_warn("i2c i/o error: rc == %d (should be 6)\n",ret);
442 }
443
444 static void mt2050_set_tv_freq(struct i2c_client *c, unsigned int freq)
445 {
446         struct tuner *t = i2c_get_clientdata(c);
447         unsigned int if2;
448
449         if (t->std & V4L2_STD_525_60) {
450                 // NTSC
451                 if2 = 45750*1000;
452         } else {
453                 // PAL
454                 if2 = 38900*1000;
455         }
456         if (V4L2_TUNER_DIGITAL_TV == t->mode) {
457                 // DVB (pinnacle 300i)
458                 if2 = 36150*1000;
459         }
460         mt2050_set_if_freq(c, freq*62500, if2);
461         mt2050_set_antenna(c, tv_antenna);
462 }
463
464 static void mt2050_set_radio_freq(struct i2c_client *c, unsigned int freq)
465 {
466         struct tuner *t = i2c_get_clientdata(c);
467         struct microtune_priv *priv = t->priv;
468         int if2 = priv->radio_if2;
469
470         mt2050_set_if_freq(c, freq * 1000 / 16, if2);
471         mt2050_set_antenna(c, radio_antenna);
472 }
473
474 static int mt2050_init(struct i2c_client *c)
475 {
476         struct tuner *t = i2c_get_clientdata(c);
477         unsigned char buf[2];
478         int ret;
479
480         buf[0]=6;
481         buf[1]=0x10;
482         ret=i2c_master_send(c,buf,2); //  power
483
484         buf[0]=0x0f;
485         buf[1]=0x0f;
486         ret=i2c_master_send(c,buf,2); // m1lo
487
488         buf[0]=0x0d;
489         ret=i2c_master_send(c,buf,1);
490         i2c_master_recv(c,buf,1);
491
492         tuner_dbg("mt2050: sro is %x\n",buf[0]);
493         t->set_tv_freq    = mt2050_set_tv_freq;
494         t->set_radio_freq = mt2050_set_radio_freq;
495         return 0;
496 }
497
498 int microtune_init(struct i2c_client *c)
499 {
500         struct microtune_priv *priv = NULL;
501         struct tuner *t = i2c_get_clientdata(c);
502         char *name;
503         unsigned char buf[21];
504         int company_code;
505
506         priv = kzalloc(sizeof(struct microtune_priv), GFP_KERNEL);
507         if (priv == NULL)
508                 return -ENOMEM;
509         t->priv = priv;
510
511         priv->radio_if2 = 10700 * 1000; /* 10.7MHz - FM radio */
512
513         memset(buf,0,sizeof(buf));
514         t->set_tv_freq    = NULL;
515         t->set_radio_freq = NULL;
516         t->standby    = NULL;
517         if (t->std & V4L2_STD_525_60) {
518                 tuner_dbg("pinnacle ntsc\n");
519                 priv->radio_if2 = 41300 * 1000;
520         } else {
521                 tuner_dbg("pinnacle pal\n");
522                 priv->radio_if2 = 33300 * 1000;
523         }
524         name = "unknown";
525
526         i2c_master_send(c,buf,1);
527         i2c_master_recv(c,buf,21);
528         if (tuner_debug) {
529                 int i;
530                 tuner_dbg("MT20xx hexdump:");
531                 for(i=0;i<21;i++) {
532                         printk(" %02x",buf[i]);
533                         if(((i+1)%8)==0) printk(" ");
534                 }
535                 printk("\n");
536         }
537         company_code = buf[0x11] << 8 | buf[0x12];
538         tuner_info("microtune: companycode=%04x part=%02x rev=%02x\n",
539                    company_code,buf[0x13],buf[0x14]);
540
541
542         if (buf[0x13] < ARRAY_SIZE(microtune_part) &&
543             NULL != microtune_part[buf[0x13]])
544                 name = microtune_part[buf[0x13]];
545         switch (buf[0x13]) {
546         case MT2032:
547                 mt2032_init(c);
548                 break;
549         case MT2050:
550                 mt2050_init(c);
551                 break;
552         default:
553                 tuner_info("microtune %s found, not (yet?) supported, sorry :-/\n",
554                            name);
555                 return 0;
556         }
557
558         strlcpy(c->name, name, sizeof(c->name));
559         tuner_info("microtune %s found, OK\n",name);
560         return 0;
561 }
562
563 /*
564  * Overrides for Emacs so that we follow Linus's tabbing style.
565  * ---------------------------------------------------------------------------
566  * Local variables:
567  * c-basic-offset: 8
568  * End:
569  */