V4L/DVB (3844): B2c2-flexcop: use fe_lgh06xf.h
[safe/jmp/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 "fe_lgh06xf.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_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, 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
176         div = params->frequency / 125;
177
178         buf[0] = (div >> 8) & 0x7f;
179         buf[1] = div & 0xff;
180         buf[2] = 0x84;  /* 0xC4 */
181         buf[3] = 0x08;
182
183         if (params->frequency < 1500000) buf[3] |= 0x10;
184
185         if (i2c_transfer(i2c, &msg, 1) != 1)
186                 return -EIO;
187         return 0;
188 }
189
190 static u8 samsung_tbmu24112_inittab[] = {
191              0x01, 0x15,
192              0x02, 0x30,
193              0x03, 0x00,
194              0x04, 0x7D,
195              0x05, 0x35,
196              0x06, 0x02,
197              0x07, 0x00,
198              0x08, 0xC3,
199              0x0C, 0x00,
200              0x0D, 0x81,
201              0x0E, 0x23,
202              0x0F, 0x12,
203              0x10, 0x7E,
204              0x11, 0x84,
205              0x12, 0xB9,
206              0x13, 0x88,
207              0x14, 0x89,
208              0x15, 0xC9,
209              0x16, 0x00,
210              0x17, 0x5C,
211              0x18, 0x00,
212              0x19, 0x00,
213              0x1A, 0x00,
214              0x1C, 0x00,
215              0x1D, 0x00,
216              0x1E, 0x00,
217              0x1F, 0x3A,
218              0x20, 0x2E,
219              0x21, 0x80,
220              0x22, 0xFF,
221              0x23, 0xC1,
222              0x28, 0x00,
223              0x29, 0x1E,
224              0x2A, 0x14,
225              0x2B, 0x0F,
226              0x2C, 0x09,
227              0x2D, 0x05,
228              0x31, 0x1F,
229              0x32, 0x19,
230              0x33, 0xFE,
231              0x34, 0x93,
232              0xff, 0xff,
233 };
234
235 static struct stv0299_config samsung_tbmu24112_config = {
236         .demod_address = 0x68,
237         .inittab = samsung_tbmu24112_inittab,
238         .mclk = 88000000UL,
239         .invert = 0,
240         .skip_reinit = 0,
241         .lock_output = STV0229_LOCKOUTPUT_LK,
242         .volt13_op0_op1 = STV0299_VOLT13_OP1,
243         .min_delay_ms = 100,
244         .set_symbol_rate = samsung_tbmu24112_set_symbol_rate,
245         .pll_set = samsung_tbmu24112_pll_set,
246 };
247
248 /* dvb-t mt352 */
249 static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
250 {
251         static u8 mt352_clock_config [] = { 0x89, 0x18, 0x2d };
252         static u8 mt352_reset [] = { 0x50, 0x80 };
253         static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
254         static u8 mt352_agc_cfg [] = { 0x67, 0x28, 0xa1 };
255         static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
256
257         mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
258         udelay(2000);
259         mt352_write(fe, mt352_reset, sizeof(mt352_reset));
260         mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
261
262         mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
263         mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
264
265         return 0;
266 }
267
268 static int samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf)
269 {
270         u32 div;
271         unsigned char bs = 0;
272
273         #define IF_FREQUENCYx6 217    /* 6 * 36.16666666667MHz */
274         div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
275
276         if (params->frequency >= 48000000 && params->frequency <= 154000000) bs = 0x09;
277         if (params->frequency >= 161000000 && params->frequency <= 439000000) bs = 0x0a;
278         if (params->frequency >= 447000000 && params->frequency <= 863000000) bs = 0x08;
279
280         pllbuf[0] = 0xc2; /* Note: non-linux standard PLL i2c address */
281         pllbuf[1] = div >> 8;
282         pllbuf[2] = div & 0xff;
283         pllbuf[3] = 0xcc;
284         pllbuf[4] = bs;
285
286         return 0;
287 }
288
289 static struct mt352_config samsung_tdtc9251dh0_config = {
290         .demod_address = 0x0f,
291         .demod_init    = samsung_tdtc9251dh0_demod_init,
292         .pll_set       = samsung_tdtc9251dh0_pll_set,
293 };
294
295 static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
296 {
297         struct flexcop_device *fc = fe->dvb->priv;
298         return request_firmware(fw, name, fc->dev);
299 }
300
301 static int lgdt3303_pll_set(struct dvb_frontend* fe,
302                             struct dvb_frontend_parameters* params)
303 {
304         struct flexcop_device *fc = fe->dvb->priv;
305         return lg_h06xf_pll_set(fe, &fc->i2c_adap, params);
306 }
307
308 static struct lgdt330x_config air2pc_atsc_hd5000_config = {
309         .demod_address       = 0x59,
310         .demod_chip          = LGDT3303,
311         .serial_mpeg         = 0x04,
312         .pll_set             = lgdt3303_pll_set,
313         .clock_polarity_flip = 1,
314 };
315
316 static struct nxt200x_config samsung_tbmv_config = {
317         .demod_address    = 0x0a,
318         .pll_address      = 0xc2,
319         .pll_desc         = &dvb_pll_samsung_tbmv,
320 };
321
322 static struct bcm3510_config air2pc_atsc_first_gen_config = {
323         .demod_address    = 0x0f,
324         .request_firmware = flexcop_fe_request_firmware,
325 };
326
327 static int skystar23_samsung_tbdu18132_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
328 {
329         u8 buf[4];
330         u32 div;
331         struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
332         struct flexcop_device *fc = fe->dvb->priv;
333
334         div = (params->frequency + (125/2)) / 125;
335
336         buf[0] = (div >> 8) & 0x7f;
337         buf[1] = (div >> 0) & 0xff;
338         buf[2] = 0x84 | ((div >> 10) & 0x60);
339         buf[3] = 0x80;
340
341         if (params->frequency < 1550000)
342                 buf[3] |= 0x02;
343
344         if (i2c_transfer(&fc->i2c_adap, &msg, 1) != 1)
345                 return -EIO;
346         return 0;
347 }
348
349 static struct mt312_config skystar23_samsung_tbdu18132_config = {
350
351         .demod_address = 0x0e,
352         .pll_set = skystar23_samsung_tbdu18132_pll_set,
353 };
354
355
356 static u8 alps_tdee4_stv0297_inittab[] = {
357         0x80, 0x01,
358         0x80, 0x00,
359         0x81, 0x01,
360         0x81, 0x00,
361         0x00, 0x09,
362         0x01, 0x69,
363         0x03, 0x00,
364         0x04, 0x00,
365         0x07, 0x00,
366         0x08, 0x00,
367         0x20, 0x00,
368         0x21, 0x40,
369         0x22, 0x00,
370         0x23, 0x00,
371         0x24, 0x40,
372         0x25, 0x88,
373         0x30, 0xff,
374         0x31, 0x00,
375         0x32, 0xff,
376         0x33, 0x00,
377         0x34, 0x50,
378         0x35, 0x7f,
379         0x36, 0x00,
380         0x37, 0x20,
381         0x38, 0x00,
382         0x40, 0x1c,
383         0x41, 0xff,
384         0x42, 0x29,
385         0x43, 0x00,
386         0x44, 0xff,
387         0x45, 0x00,
388         0x46, 0x00,
389         0x49, 0x04,
390         0x4a, 0x00,
391         0x4b, 0xf8,
392         0x52, 0x30,
393         0x55, 0xae,
394         0x56, 0x47,
395         0x57, 0xe1,
396         0x58, 0x3a,
397         0x5a, 0x1e,
398         0x5b, 0x34,
399         0x60, 0x00,
400         0x63, 0x00,
401         0x64, 0x00,
402         0x65, 0x00,
403         0x66, 0x00,
404         0x67, 0x00,
405         0x68, 0x00,
406         0x69, 0x00,
407         0x6a, 0x02,
408         0x6b, 0x00,
409         0x70, 0xff,
410         0x71, 0x00,
411         0x72, 0x00,
412         0x73, 0x00,
413         0x74, 0x0c,
414         0x80, 0x00,
415         0x81, 0x00,
416         0x82, 0x00,
417         0x83, 0x00,
418         0x84, 0x04,
419         0x85, 0x80,
420         0x86, 0x24,
421         0x87, 0x78,
422         0x88, 0x10,
423         0x89, 0x00,
424         0x90, 0x01,
425         0x91, 0x01,
426         0xa0, 0x04,
427         0xa1, 0x00,
428         0xa2, 0x00,
429         0xb0, 0x91,
430         0xb1, 0x0b,
431         0xc0, 0x53,
432         0xc1, 0x70,
433         0xc2, 0x12,
434         0xd0, 0x00,
435         0xd1, 0x00,
436         0xd2, 0x00,
437         0xd3, 0x00,
438         0xd4, 0x00,
439         0xd5, 0x00,
440         0xde, 0x00,
441         0xdf, 0x00,
442         0x61, 0x49,
443         0x62, 0x0b,
444         0x53, 0x08,
445         0x59, 0x08,
446         0xff, 0xff,
447 };
448
449 static struct stv0297_config alps_tdee4_stv0297_config = {
450         .demod_address = 0x1c,
451         .inittab = alps_tdee4_stv0297_inittab,
452 //      .invert = 1,
453 //      .pll_set = alps_tdee4_stv0297_pll_set,
454 };
455
456 /* try to figure out the frontend, each card/box can have on of the following list */
457 int flexcop_frontend_init(struct flexcop_device *fc)
458 {
459         struct dvb_frontend_ops *ops;
460
461         /* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */
462         if ((fc->fe = stv0299_attach(&samsung_tbmu24112_config, &fc->i2c_adap)) != NULL) {
463                 ops = fc->fe->ops;
464
465                 ops->set_voltage = flexcop_set_voltage;
466
467                 fc->fe_sleep             = ops->sleep;
468                 ops->sleep               = flexcop_sleep;
469
470                 fc->dev_type          = FC_SKY;
471                 info("found the stv0299 at i2c address: 0x%02x",samsung_tbmu24112_config.demod_address);
472         } else
473         /* try the air dvb-t (mt352/Samsung tdtc9251dh0(??)) */
474         if ((fc->fe = mt352_attach(&samsung_tdtc9251dh0_config, &fc->i2c_adap)) != NULL ) {
475                 fc->dev_type          = FC_AIR_DVB;
476                 info("found the mt352 at i2c address: 0x%02x",samsung_tdtc9251dh0_config.demod_address);
477         } else
478         /* try the air atsc 2nd generation (nxt2002) */
479         if ((fc->fe = nxt200x_attach(&samsung_tbmv_config, &fc->i2c_adap)) != NULL) {
480                 fc->dev_type          = FC_AIR_ATSC2;
481                 info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address);
482         } else
483         /* try the air atsc 3nd generation (lgdt3303) */
484         if ((fc->fe = lgdt330x_attach(&air2pc_atsc_hd5000_config, &fc->i2c_adap)) != NULL) {
485                 fc->dev_type          = FC_AIR_ATSC3;
486                 info("found the lgdt3303 at i2c address: 0x%02x",air2pc_atsc_hd5000_config.demod_address);
487         } else
488         /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */
489         if ((fc->fe = bcm3510_attach(&air2pc_atsc_first_gen_config, &fc->i2c_adap)) != NULL) {
490                 fc->dev_type          = FC_AIR_ATSC1;
491                 info("found the bcm3510 at i2c address: 0x%02x",air2pc_atsc_first_gen_config.demod_address);
492         } else
493         /* try the cable dvb (stv0297) */
494         if ((fc->fe = stv0297_attach(&alps_tdee4_stv0297_config, &fc->i2c_adap)) != NULL) {
495                 fc->dev_type                        = FC_CABLE;
496                 info("found the stv0297 at i2c address: 0x%02x",alps_tdee4_stv0297_config.demod_address);
497         } else
498         /* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */
499         if ((fc->fe = vp310_mt312_attach(&skystar23_samsung_tbdu18132_config, &fc->i2c_adap)) != NULL) {
500                 ops = fc->fe->ops;
501
502                 ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
503                 ops->diseqc_send_burst      = flexcop_diseqc_send_burst;
504                 ops->set_tone               = flexcop_set_tone;
505                 ops->set_voltage            = flexcop_set_voltage;
506
507                 fc->fe_sleep                = ops->sleep;
508                 ops->sleep                  = flexcop_sleep;
509
510                 fc->dev_type                = FC_SKY_OLD;
511                 info("found the vp310 (aka mt312) at i2c address: 0x%02x",skystar23_samsung_tbdu18132_config.demod_address);
512         }
513
514         if (fc->fe == NULL) {
515                 err("no frontend driver found for this B2C2/FlexCop adapter");
516                 return -ENODEV;
517         } else {
518                 if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) {
519                         err("frontend registration failed!");
520                         ops = fc->fe->ops;
521                         if (ops->release != NULL)
522                                 ops->release(fc->fe);
523                         fc->fe = NULL;
524                         return -EINVAL;
525                 }
526         }
527         fc->init_state |= FC_STATE_FE_INIT;
528         return 0;
529 }
530
531 void flexcop_frontend_exit(struct flexcop_device *fc)
532 {
533         if (fc->init_state & FC_STATE_FE_INIT)
534                 dvb_unregister_frontend(fc->fe);
535
536         fc->init_state &= ~FC_STATE_FE_INIT;
537 }