V4L/DVB (4819): Dib0700: Add support for new revision of Nova-T Stick
[linux-2.6] / drivers / media / dvb / b2c2 / flexcop-fe-tuner.c
1 /*
2  * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
3  *
4  * flexcop-fe-tuner.c - methods for attaching a frontend and controlling DiSEqC.
5  *
6  * see flexcop.c for copyright information.
7  */
8 #include "flexcop.h"
9
10 #include "stv0299.h"
11 #include "mt352.h"
12 #include "nxt200x.h"
13 #include "bcm3510.h"
14 #include "stv0297.h"
15 #include "mt312.h"
16 #include "lgdt330x.h"
17 #include "lg_h06xf.h"
18 #include "dvb-pll.h"
19
20 /* lnb control */
21
22 static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
23 {
24         struct flexcop_device *fc = fe->dvb->priv;
25         flexcop_ibi_value v;
26         deb_tuner("polarity/voltage = %u\n", voltage);
27
28         v = fc->read_ibi_reg(fc, misc_204);
29         switch (voltage) {
30                 case SEC_VOLTAGE_OFF:
31                         v.misc_204.ACPI1_sig = 1;
32                         break;
33                 case SEC_VOLTAGE_13:
34                         v.misc_204.ACPI1_sig = 0;
35                         v.misc_204.LNB_L_H_sig = 0;
36                         break;
37                 case SEC_VOLTAGE_18:
38                         v.misc_204.ACPI1_sig = 0;
39                         v.misc_204.LNB_L_H_sig = 1;
40                         break;
41                 default:
42                         err("unknown SEC_VOLTAGE value");
43                         return -EINVAL;
44         }
45         return fc->write_ibi_reg(fc, misc_204, v);
46 }
47
48 static int flexcop_sleep(struct dvb_frontend* fe)
49 {
50         struct flexcop_device *fc = fe->dvb->priv;
51 /*      flexcop_ibi_value v = fc->read_ibi_reg(fc,misc_204); */
52
53         if (fc->fe_sleep)
54                 return fc->fe_sleep(fe);
55
56 /*      v.misc_204.ACPI3_sig = 1;
57         fc->write_ibi_reg(fc,misc_204,v);*/
58
59         return 0;
60 }
61
62 static int flexcop_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
63 {
64         /* u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc }; */
65         struct flexcop_device *fc = fe->dvb->priv;
66         flexcop_ibi_value v;
67         u16 ax;
68         v.raw = 0;
69
70         deb_tuner("tone = %u\n",tone);
71
72         switch (tone) {
73                 case SEC_TONE_ON:
74                         ax = 0x01ff;
75                         break;
76                 case SEC_TONE_OFF:
77                         ax = 0;
78                         break;
79                 default:
80                         err("unknown SEC_TONE value");
81                         return -EINVAL;
82         }
83
84         v.lnb_switch_freq_200.LNB_CTLPrescaler_sig = 1; /* divide by 2 */
85
86         v.lnb_switch_freq_200.LNB_CTLHighCount_sig = ax;
87         v.lnb_switch_freq_200.LNB_CTLLowCount_sig  = ax == 0 ? 0x1ff : ax;
88
89         return fc->write_ibi_reg(fc,lnb_switch_freq_200,v);
90 }
91
92 static void flexcop_diseqc_send_bit(struct dvb_frontend* fe, int data)
93 {
94         flexcop_set_tone(fe, SEC_TONE_ON);
95         udelay(data ? 500 : 1000);
96         flexcop_set_tone(fe, SEC_TONE_OFF);
97         udelay(data ? 1000 : 500);
98 }
99
100 static void flexcop_diseqc_send_byte(struct dvb_frontend* fe, int data)
101 {
102         int i, par = 1, d;
103
104         for (i = 7; i >= 0; i--) {
105                 d = (data >> i) & 1;
106                 par ^= d;
107                 flexcop_diseqc_send_bit(fe, d);
108         }
109
110         flexcop_diseqc_send_bit(fe, par);
111 }
112
113 static int flexcop_send_diseqc_msg(struct dvb_frontend* fe, int len, u8 *msg, unsigned long burst)
114 {
115         int i;
116
117         flexcop_set_tone(fe, SEC_TONE_OFF);
118         mdelay(16);
119
120         for (i = 0; i < len; i++)
121                 flexcop_diseqc_send_byte(fe,msg[i]);
122
123         mdelay(16);
124
125         if (burst != -1) {
126                 if (burst)
127                         flexcop_diseqc_send_byte(fe, 0xff);
128                 else {
129                         flexcop_set_tone(fe, SEC_TONE_ON);
130                         udelay(12500);
131                         flexcop_set_tone(fe, SEC_TONE_OFF);
132                 }
133                 msleep(20);
134         }
135         return 0;
136 }
137
138 static int flexcop_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
139 {
140         return flexcop_send_diseqc_msg(fe, cmd->msg_len, cmd->msg, 0);
141 }
142
143 static int flexcop_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
144 {
145         return flexcop_send_diseqc_msg(fe, 0, NULL, minicmd);
146 }
147
148 /* dvb-s stv0299 */
149 static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
150 {
151         u8 aclk = 0;
152         u8 bclk = 0;
153
154         if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
155         else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
156         else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
157         else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
158         else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
159         else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
160
161         stv0299_writereg (fe, 0x13, aclk);
162         stv0299_writereg (fe, 0x14, bclk);
163         stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff);
164         stv0299_writereg (fe, 0x20, (ratio >>  8) & 0xff);
165         stv0299_writereg (fe, 0x21, (ratio      ) & 0xf0);
166
167         return 0;
168 }
169
170 static int samsung_tbmu24112_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params)
171 {
172         u8 buf[4];
173         u32 div;
174         struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
175         struct flexcop_device *fc = fe->dvb->priv;
176
177         div = params->frequency / 125;
178
179         buf[0] = (div >> 8) & 0x7f;
180         buf[1] = div & 0xff;
181         buf[2] = 0x84;  /* 0xC4 */
182         buf[3] = 0x08;
183
184         if (params->frequency < 1500000) buf[3] |= 0x10;
185
186         if (fe->ops.i2c_gate_ctrl)
187                 fe->ops.i2c_gate_ctrl(fe, 1);
188         if (i2c_transfer(&fc->i2c_adap, &msg, 1) != 1) {
189                 return -EIO;
190         }
191         return 0;
192 }
193
194 static u8 samsung_tbmu24112_inittab[] = {
195              0x01, 0x15,
196              0x02, 0x30,
197              0x03, 0x00,
198              0x04, 0x7D,
199              0x05, 0x35,
200              0x06, 0x02,
201              0x07, 0x00,
202              0x08, 0xC3,
203              0x0C, 0x00,
204              0x0D, 0x81,
205              0x0E, 0x23,
206              0x0F, 0x12,
207              0x10, 0x7E,
208              0x11, 0x84,
209              0x12, 0xB9,
210              0x13, 0x88,
211              0x14, 0x89,
212              0x15, 0xC9,
213              0x16, 0x00,
214              0x17, 0x5C,
215              0x18, 0x00,
216              0x19, 0x00,
217              0x1A, 0x00,
218              0x1C, 0x00,
219              0x1D, 0x00,
220              0x1E, 0x00,
221              0x1F, 0x3A,
222              0x20, 0x2E,
223              0x21, 0x80,
224              0x22, 0xFF,
225              0x23, 0xC1,
226              0x28, 0x00,
227              0x29, 0x1E,
228              0x2A, 0x14,
229              0x2B, 0x0F,
230              0x2C, 0x09,
231              0x2D, 0x05,
232              0x31, 0x1F,
233              0x32, 0x19,
234              0x33, 0xFE,
235              0x34, 0x93,
236              0xff, 0xff,
237 };
238
239 static struct stv0299_config samsung_tbmu24112_config = {
240         .demod_address = 0x68,
241         .inittab = samsung_tbmu24112_inittab,
242         .mclk = 88000000UL,
243         .invert = 0,
244         .skip_reinit = 0,
245         .lock_output = STV0229_LOCKOUTPUT_LK,
246         .volt13_op0_op1 = STV0299_VOLT13_OP1,
247         .min_delay_ms = 100,
248         .set_symbol_rate = samsung_tbmu24112_set_symbol_rate,
249 };
250
251 /* dvb-t mt352 */
252 static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
253 {
254         static u8 mt352_clock_config [] = { 0x89, 0x18, 0x2d };
255         static u8 mt352_reset [] = { 0x50, 0x80 };
256         static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
257         static u8 mt352_agc_cfg [] = { 0x67, 0x28, 0xa1 };
258         static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
259
260         mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
261         udelay(2000);
262         mt352_write(fe, mt352_reset, sizeof(mt352_reset));
263         mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
264
265         mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
266         mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
267
268         return 0;
269 }
270
271 static int samsung_tdtc9251dh0_calc_regs(struct dvb_frontend* fe, struct dvb_frontend_parameters *params, u8* pllbuf, int buf_len)
272 {
273         u32 div;
274         unsigned char bs = 0;
275
276         if (buf_len < 5)
277                 return -EINVAL;
278
279         #define IF_FREQUENCYx6 217    /* 6 * 36.16666666667MHz */
280         div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
281
282         if (params->frequency >= 48000000 && params->frequency <= 154000000) bs = 0x09;
283         if (params->frequency >= 161000000 && params->frequency <= 439000000) bs = 0x0a;
284         if (params->frequency >= 447000000 && params->frequency <= 863000000) bs = 0x08;
285
286         pllbuf[0] = 0x61;
287         pllbuf[1] = div >> 8;
288         pllbuf[2] = div & 0xff;
289         pllbuf[3] = 0xcc;
290         pllbuf[4] = bs;
291
292         return 5;
293 }
294
295 static struct mt352_config samsung_tdtc9251dh0_config = {
296         .demod_address = 0x0f,
297         .demod_init    = samsung_tdtc9251dh0_demod_init,
298 };
299
300 static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
301 {
302         struct flexcop_device *fc = fe->dvb->priv;
303         return request_firmware(fw, name, fc->dev);
304 }
305
306 static int lgdt3303_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params)
307 {
308         struct flexcop_device *fc = fe->dvb->priv;
309         return lg_h06xf_pll_set(fe, &fc->i2c_adap, params);
310 }
311
312 static struct lgdt330x_config air2pc_atsc_hd5000_config = {
313         .demod_address       = 0x59,
314         .demod_chip          = LGDT3303,
315         .serial_mpeg         = 0x04,
316         .clock_polarity_flip = 1,
317 };
318
319 static struct nxt200x_config samsung_tbmv_config = {
320         .demod_address    = 0x0a,
321 };
322
323 static struct bcm3510_config air2pc_atsc_first_gen_config = {
324         .demod_address    = 0x0f,
325         .request_firmware = flexcop_fe_request_firmware,
326 };
327
328 static int skystar23_samsung_tbdu18132_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params)
329 {
330         u8 buf[4];
331         u32 div;
332         struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
333         struct flexcop_device *fc = fe->dvb->priv;
334
335         div = (params->frequency + (125/2)) / 125;
336
337         buf[0] = (div >> 8) & 0x7f;
338         buf[1] = (div >> 0) & 0xff;
339         buf[2] = 0x84 | ((div >> 10) & 0x60);
340         buf[3] = 0x80;
341
342         if (params->frequency < 1550000)
343                 buf[3] |= 0x02;
344
345         if (fe->ops.i2c_gate_ctrl)
346                 fe->ops.i2c_gate_ctrl(fe, 1);
347         if (i2c_transfer(&fc->i2c_adap, &msg, 1) != 1)
348                 return -EIO;
349         return 0;
350 }
351
352 static struct mt312_config skystar23_samsung_tbdu18132_config = {
353
354         .demod_address = 0x0e,
355 };
356
357 static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe,
358                                                struct dvb_frontend_parameters *fep)
359 {
360         struct flexcop_device *fc = fe->dvb->priv;
361         u8 buf[4];
362         u16 div;
363         int ret;
364
365 /*  62.5 kHz * 10 */
366 #define REF_FREQ    625
367 #define FREQ_OFFSET 36125
368
369         div = ((fep->frequency/1000 + FREQ_OFFSET ) * 10)  / REF_FREQ; // 4 MHz = 4000 KHz
370
371         buf[0] = (u8)( div >> 8) & 0x7f;
372         buf[1] = (u8)        div & 0xff;
373
374 /* F(osc) = N * Reference Freq. (62.5 kHz)
375  * byte 2 :  0 N14 N13 N12 N11 N10 N9  N8
376  * byte 3 : N7 N6  N5  N4  N3  N2  N1  N0
377  * byte 4 : 1  *   *   AGD R3  R2  R1  R0
378  * byte 5 : C1 *   RE  RTS BS4 BS3 BS2 BS1
379  * AGD = 1, R3 R2 R1 R0 = 0 1 0 1 => byte 4 = 1**10101 = 0x95 */
380         buf[2] = 0x95;
381
382 // Range(MHz)  C1 *  RE RTS BS4 BS3 BS2 BS1  Byte 5
383 //  47 - 153   0  *  0   0   0   0   0   1   0x01
384 // 153 - 430   0  *  0   0   0   0   1   0   0x02
385 // 430 - 822   0  *  0   0   1   0   0   0   0x08
386 // 822 - 862   1  *  0   0   1   0   0   0   0x88
387
388              if (fep->frequency <= 153000000) buf[3] = 0x01;
389         else if (fep->frequency <= 430000000) buf[3] = 0x02;
390         else if (fep->frequency <= 822000000) buf[3] = 0x08;
391         else buf[3] = 0x88;
392
393         if (fe->ops.i2c_gate_ctrl)
394                 fe->ops.i2c_gate_ctrl(fe, 1);
395         deb_tuner("tuner buffer for %d Hz: %x %x %x %x\n",fep->frequency, buf[0],buf[1],buf[2],buf[3]);
396         ret = fc->i2c_request(fc,FC_WRITE,FC_I2C_PORT_TUNER,0x61,buf[0],&buf[1],3);
397         deb_tuner("tuner write returned: %d\n",ret);
398
399         return 0;
400 }
401
402 static u8 alps_tdee4_stv0297_inittab[] = {
403         0x80, 0x01,
404         0x80, 0x00,
405         0x81, 0x01,
406         0x81, 0x00,
407         0x00, 0x09,
408         0x01, 0x69,
409         0x03, 0x00,
410         0x04, 0x00,
411         0x07, 0x00,
412         0x08, 0x00,
413         0x20, 0x00,
414         0x21, 0x40,
415         0x22, 0x00,
416         0x23, 0x00,
417         0x24, 0x40,
418         0x25, 0x88,
419         0x30, 0xff,
420         0x31, 0x00,
421         0x32, 0xff,
422         0x33, 0x00,
423         0x34, 0x50,
424         0x35, 0x7f,
425         0x36, 0x00,
426         0x37, 0x20,
427         0x38, 0x00,
428         0x40, 0x1c,
429         0x41, 0xff,
430         0x42, 0x29,
431         0x43, 0x00,
432         0x44, 0xff,
433         0x45, 0x00,
434         0x46, 0x00,
435         0x49, 0x04,
436         0x4a, 0x00,
437         0x4b, 0xf8,
438         0x52, 0x30,
439         0x55, 0xae,
440         0x56, 0x47,
441         0x57, 0xe1,
442         0x58, 0x3a,
443         0x5a, 0x1e,
444         0x5b, 0x34,
445         0x60, 0x00,
446         0x63, 0x00,
447         0x64, 0x00,
448         0x65, 0x00,
449         0x66, 0x00,
450         0x67, 0x00,
451         0x68, 0x00,
452         0x69, 0x00,
453         0x6a, 0x02,
454         0x6b, 0x00,
455         0x70, 0xff,
456         0x71, 0x00,
457         0x72, 0x00,
458         0x73, 0x00,
459         0x74, 0x0c,
460         0x80, 0x00,
461         0x81, 0x00,
462         0x82, 0x00,
463         0x83, 0x00,
464         0x84, 0x04,
465         0x85, 0x80,
466         0x86, 0x24,
467         0x87, 0x78,
468         0x88, 0x10,
469         0x89, 0x00,
470         0x90, 0x01,
471         0x91, 0x01,
472         0xa0, 0x04,
473         0xa1, 0x00,
474         0xa2, 0x00,
475         0xb0, 0x91,
476         0xb1, 0x0b,
477         0xc0, 0x53,
478         0xc1, 0x70,
479         0xc2, 0x12,
480         0xd0, 0x00,
481         0xd1, 0x00,
482         0xd2, 0x00,
483         0xd3, 0x00,
484         0xd4, 0x00,
485         0xd5, 0x00,
486         0xde, 0x00,
487         0xdf, 0x00,
488         0x61, 0x49,
489         0x62, 0x0b,
490         0x53, 0x08,
491         0x59, 0x08,
492         0xff, 0xff,
493 };
494
495 static struct stv0297_config alps_tdee4_stv0297_config = {
496         .demod_address = 0x1c,
497         .inittab = alps_tdee4_stv0297_inittab,
498 //      .invert = 1,
499 //      .pll_set = alps_tdee4_stv0297_pll_set,
500 };
501
502 /* try to figure out the frontend, each card/box can have on of the following list */
503 int flexcop_frontend_init(struct flexcop_device *fc)
504 {
505         struct dvb_frontend_ops *ops;
506
507         /* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */
508         if ((fc->fe = dvb_attach(stv0299_attach, &samsung_tbmu24112_config, &fc->i2c_adap)) != NULL) {
509                 ops = &fc->fe->ops;
510
511                 ops->tuner_ops.set_params = samsung_tbmu24112_tuner_set_params;
512
513                 ops->set_voltage = flexcop_set_voltage;
514
515                 fc->fe_sleep             = ops->sleep;
516                 ops->sleep               = flexcop_sleep;
517
518                 fc->dev_type          = FC_SKY;
519                 info("found the stv0299 at i2c address: 0x%02x",samsung_tbmu24112_config.demod_address);
520         } else
521         /* try the air dvb-t (mt352/Samsung tdtc9251dh0(??)) */
522         if ((fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, &fc->i2c_adap)) != NULL ) {
523                 fc->dev_type          = FC_AIR_DVB;
524                 fc->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs;
525                 info("found the mt352 at i2c address: 0x%02x",samsung_tdtc9251dh0_config.demod_address);
526         } else
527         /* try the air atsc 2nd generation (nxt2002) */
528         if ((fc->fe = dvb_attach(nxt200x_attach, &samsung_tbmv_config, &fc->i2c_adap)) != NULL) {
529                 fc->dev_type          = FC_AIR_ATSC2;
530                 dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL, &dvb_pll_samsung_tbmv);
531                 info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address);
532         } else
533         /* try the air atsc 3nd generation (lgdt3303) */
534         if ((fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, &fc->i2c_adap)) != NULL) {
535                 fc->dev_type          = FC_AIR_ATSC3;
536                 fc->fe->ops.tuner_ops.set_params = lgdt3303_tuner_set_params;
537                 info("found the lgdt3303 at i2c address: 0x%02x",air2pc_atsc_hd5000_config.demod_address);
538         } else
539         /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */
540         if ((fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, &fc->i2c_adap)) != NULL) {
541                 fc->dev_type          = FC_AIR_ATSC1;
542                 info("found the bcm3510 at i2c address: 0x%02x",air2pc_atsc_first_gen_config.demod_address);
543         } else
544         /* try the cable dvb (stv0297) */
545         if ((fc->fe = dvb_attach(stv0297_attach, &alps_tdee4_stv0297_config, &fc->i2c_adap)) != NULL) {
546                 fc->dev_type                        = FC_CABLE;
547                 fc->fe->ops.tuner_ops.set_params = alps_tdee4_stv0297_tuner_set_params;
548                 info("found the stv0297 at i2c address: 0x%02x",alps_tdee4_stv0297_config.demod_address);
549         } else
550         /* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */
551         if ((fc->fe = dvb_attach(vp310_mt312_attach, &skystar23_samsung_tbdu18132_config, &fc->i2c_adap)) != NULL) {
552                 ops = &fc->fe->ops;
553
554                 ops->tuner_ops.set_params = skystar23_samsung_tbdu18132_tuner_set_params;
555
556                 ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
557                 ops->diseqc_send_burst      = flexcop_diseqc_send_burst;
558                 ops->set_tone               = flexcop_set_tone;
559                 ops->set_voltage            = flexcop_set_voltage;
560
561                 fc->fe_sleep                = ops->sleep;
562                 ops->sleep                  = flexcop_sleep;
563
564                 fc->dev_type                = FC_SKY_OLD;
565                 info("found the vp310 (aka mt312) at i2c address: 0x%02x",skystar23_samsung_tbdu18132_config.demod_address);
566         }
567
568         if (fc->fe == NULL) {
569                 err("no frontend driver found for this B2C2/FlexCop adapter");
570                 return -ENODEV;
571         } else {
572                 if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) {
573                         err("frontend registration failed!");
574                         dvb_frontend_detach(fc->fe);
575                         fc->fe = NULL;
576                         return -EINVAL;
577                 }
578         }
579         fc->init_state |= FC_STATE_FE_INIT;
580         return 0;
581 }
582
583 void flexcop_frontend_exit(struct flexcop_device *fc)
584 {
585         if (fc->init_state & FC_STATE_FE_INIT) {
586                 dvb_unregister_frontend(fc->fe);
587                 dvb_frontend_detach(fc->fe);
588         }
589
590         fc->init_state &= ~FC_STATE_FE_INIT;
591 }