]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/media/dvb/b2c2/flexcop-fe-tuner.c
[PATCH] dvb: Remove broken stv0299 enhanced tuning code
[mv-sheeva.git] / 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 "nxt2002.h"
13 #include "bcm3510.h"
14 #include "stv0297.h"
15 #include "mt312.h"
16
17 /* lnb control */
18
19 static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
20 {
21         struct flexcop_device *fc = fe->dvb->priv;
22         flexcop_ibi_value v;
23         deb_tuner("polarity/voltage = %u\n", voltage);
24
25         v = fc->read_ibi_reg(fc, misc_204);
26         switch (voltage) {
27                 case SEC_VOLTAGE_OFF:
28                         v.misc_204.ACPI1_sig = 1;
29                         break;
30                 case SEC_VOLTAGE_13:
31                         v.misc_204.ACPI1_sig = 0;
32                         v.misc_204.LNB_L_H_sig = 0;
33                         break;
34                 case SEC_VOLTAGE_18:
35                         v.misc_204.ACPI1_sig = 0;
36                         v.misc_204.LNB_L_H_sig = 1;
37                         break;
38                 default:
39                         err("unknown SEC_VOLTAGE value");
40                         return -EINVAL;
41         }
42         return fc->write_ibi_reg(fc, misc_204, v);
43 }
44
45 static int flexcop_sleep(struct dvb_frontend* fe)
46 {
47         struct flexcop_device *fc = fe->dvb->priv;
48 /*      flexcop_ibi_value v = fc->read_ibi_reg(fc,misc_204); */
49
50         if (fc->fe_sleep)
51                 return fc->fe_sleep(fe);
52
53 /*      v.misc_204.ACPI3_sig = 1;
54         fc->write_ibi_reg(fc,misc_204,v);*/
55
56         return 0;
57 }
58
59 static int flexcop_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
60 {
61         /* u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc }; */
62         struct flexcop_device *fc = fe->dvb->priv;
63         flexcop_ibi_value v;
64         u16 ax;
65         v.raw = 0;
66
67         deb_tuner("tone = %u\n",tone);
68
69         switch (tone) {
70                 case SEC_TONE_ON:
71                         ax = 0x01ff;
72                         break;
73                 case SEC_TONE_OFF:
74                         ax = 0;
75                         break;
76                 default:
77                         err("unknown SEC_TONE value");
78                         return -EINVAL;
79         }
80
81         v.lnb_switch_freq_200.LNB_CTLPrescaler_sig = 1; /* divide by 2 */
82
83         v.lnb_switch_freq_200.LNB_CTLHighCount_sig = ax;
84         v.lnb_switch_freq_200.LNB_CTLLowCount_sig  = ax == 0 ? 0x1ff : ax;
85
86         return fc->write_ibi_reg(fc,lnb_switch_freq_200,v);
87 }
88
89 static void flexcop_diseqc_send_bit(struct dvb_frontend* fe, int data)
90 {
91         flexcop_set_tone(fe, SEC_TONE_ON);
92         udelay(data ? 500 : 1000);
93         flexcop_set_tone(fe, SEC_TONE_OFF);
94         udelay(data ? 1000 : 500);
95 }
96
97 static void flexcop_diseqc_send_byte(struct dvb_frontend* fe, int data)
98 {
99         int i, par = 1, d;
100
101         for (i = 7; i >= 0; i--) {
102                 d = (data >> i) & 1;
103                 par ^= d;
104                 flexcop_diseqc_send_bit(fe, d);
105         }
106
107         flexcop_diseqc_send_bit(fe, par);
108 }
109
110 static int flexcop_send_diseqc_msg(struct dvb_frontend* fe, int len, u8 *msg, unsigned long burst)
111 {
112         int i;
113
114         flexcop_set_tone(fe, SEC_TONE_OFF);
115         mdelay(16);
116
117         for (i = 0; i < len; i++)
118                 flexcop_diseqc_send_byte(fe,msg[i]);
119
120         mdelay(16);
121
122         if (burst != -1) {
123                 if (burst)
124                         flexcop_diseqc_send_byte(fe, 0xff);
125                 else {
126                         flexcop_set_tone(fe, SEC_TONE_ON);
127                         udelay(12500);
128                         flexcop_set_tone(fe, SEC_TONE_OFF);
129                 }
130                 msleep(20);
131         }
132         return 0;
133 }
134
135 static int flexcop_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
136 {
137         return flexcop_send_diseqc_msg(fe, cmd->msg_len, cmd->msg, 0);
138 }
139
140 static int flexcop_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
141 {
142         return flexcop_send_diseqc_msg(fe, 0, NULL, minicmd);
143 }
144
145 /* dvb-s stv0299 */
146 static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
147 {
148         u8 aclk = 0;
149         u8 bclk = 0;
150
151         if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
152         else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
153         else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
154         else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
155         else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
156         else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
157
158         stv0299_writereg (fe, 0x13, aclk);
159         stv0299_writereg (fe, 0x14, bclk);
160         stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff);
161         stv0299_writereg (fe, 0x20, (ratio >>  8) & 0xff);
162         stv0299_writereg (fe, 0x21, (ratio      ) & 0xf0);
163
164         return 0;
165 }
166
167 static int samsung_tbmu24112_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
168 {
169         u8 buf[4];
170         u32 div;
171         struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
172
173         div = params->frequency / 125;
174
175         buf[0] = (div >> 8) & 0x7f;
176         buf[1] = div & 0xff;
177         buf[2] = 0x84;  /* 0xC4 */
178         buf[3] = 0x08;
179
180         if (params->frequency < 1500000) buf[3] |= 0x10;
181
182         if (i2c_transfer(i2c, &msg, 1) != 1)
183                 return -EIO;
184         return 0;
185 }
186
187 static u8 samsung_tbmu24112_inittab[] = {
188              0x01, 0x15,
189              0x02, 0x30,
190              0x03, 0x00,
191              0x04, 0x7D,
192              0x05, 0x35,
193              0x06, 0x02,
194              0x07, 0x00,
195              0x08, 0xC3,
196              0x0C, 0x00,
197              0x0D, 0x81,
198              0x0E, 0x23,
199              0x0F, 0x12,
200              0x10, 0x7E,
201              0x11, 0x84,
202              0x12, 0xB9,
203              0x13, 0x88,
204              0x14, 0x89,
205              0x15, 0xC9,
206              0x16, 0x00,
207              0x17, 0x5C,
208              0x18, 0x00,
209              0x19, 0x00,
210              0x1A, 0x00,
211              0x1C, 0x00,
212              0x1D, 0x00,
213              0x1E, 0x00,
214              0x1F, 0x3A,
215              0x20, 0x2E,
216              0x21, 0x80,
217              0x22, 0xFF,
218              0x23, 0xC1,
219              0x28, 0x00,
220              0x29, 0x1E,
221              0x2A, 0x14,
222              0x2B, 0x0F,
223              0x2C, 0x09,
224              0x2D, 0x05,
225              0x31, 0x1F,
226              0x32, 0x19,
227              0x33, 0xFE,
228              0x34, 0x93,
229              0xff, 0xff,
230 };
231
232 static struct stv0299_config samsung_tbmu24112_config = {
233         .demod_address = 0x68,
234         .inittab = samsung_tbmu24112_inittab,
235         .mclk = 88000000UL,
236         .invert = 0,
237         .skip_reinit = 0,
238         .lock_output = STV0229_LOCKOUTPUT_LK,
239         .volt13_op0_op1 = STV0299_VOLT13_OP1,
240         .min_delay_ms = 100,
241         .set_symbol_rate = samsung_tbmu24112_set_symbol_rate,
242         .pll_set = samsung_tbmu24112_pll_set,
243 };
244
245 /* dvb-t mt352 */
246 static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
247 {
248         static u8 mt352_clock_config [] = { 0x89, 0x18, 0x2d };
249         static u8 mt352_reset [] = { 0x50, 0x80 };
250         static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
251         static u8 mt352_agc_cfg [] = { 0x67, 0x28, 0xa1 };
252         static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
253
254         mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
255         udelay(2000);
256         mt352_write(fe, mt352_reset, sizeof(mt352_reset));
257         mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
258
259         mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
260         mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
261
262         return 0;
263 }
264
265 static int samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf)
266 {
267         u32 div;
268         unsigned char bs = 0;
269
270         #define IF_FREQUENCYx6 217    /* 6 * 36.16666666667MHz */
271         div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
272
273         if (params->frequency >= 48000000 && params->frequency <= 154000000) bs = 0x09;
274         if (params->frequency >= 161000000 && params->frequency <= 439000000) bs = 0x0a;
275         if (params->frequency >= 447000000 && params->frequency <= 863000000) bs = 0x08;
276
277         pllbuf[0] = 0xc2; /* Note: non-linux standard PLL i2c address */
278         pllbuf[1] = div >> 8;
279         pllbuf[2] = div & 0xff;
280         pllbuf[3] = 0xcc;
281         pllbuf[4] = bs;
282
283         return 0;
284 }
285
286 static struct mt352_config samsung_tdtc9251dh0_config = {
287         .demod_address = 0x0f,
288         .demod_init    = samsung_tdtc9251dh0_demod_init,
289         .pll_set       = samsung_tdtc9251dh0_pll_set,
290 };
291
292 static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
293 {
294         struct flexcop_device *fc = fe->dvb->priv;
295         return request_firmware(fw, name, fc->dev);
296 }
297
298 static struct nxt2002_config samsung_tbmv_config = {
299         .demod_address    = 0x0a,
300         .request_firmware = flexcop_fe_request_firmware,
301 };
302
303 static struct bcm3510_config air2pc_atsc_first_gen_config = {
304         .demod_address    = 0x0f,
305         .request_firmware = flexcop_fe_request_firmware,
306 };
307
308 static int skystar23_samsung_tbdu18132_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
309 {
310         u8 buf[4];
311         u32 div;
312         struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
313         struct flexcop_device *fc = fe->dvb->priv;
314
315         div = (params->frequency + (125/2)) / 125;
316
317         buf[0] = (div >> 8) & 0x7f;
318         buf[1] = (div >> 0) & 0xff;
319         buf[2] = 0x84 | ((div >> 10) & 0x60);
320         buf[3] = 0x80;
321
322         if (params->frequency < 1550000)
323                 buf[3] |= 0x02;
324
325         if (i2c_transfer(&fc->i2c_adap, &msg, 1) != 1)
326                 return -EIO;
327         return 0;
328 }
329
330 static struct mt312_config skystar23_samsung_tbdu18132_config = {
331
332         .demod_address = 0x0e,
333         .pll_set = skystar23_samsung_tbdu18132_pll_set,
334 };
335
336
337 static u8 alps_tdee4_stv0297_inittab[] = {
338         0x80, 0x01,
339         0x80, 0x00,
340         0x81, 0x01,
341         0x81, 0x00,
342         0x00, 0x09,
343         0x01, 0x69,
344         0x03, 0x00,
345         0x04, 0x00,
346         0x07, 0x00,
347         0x08, 0x00,
348         0x20, 0x00,
349         0x21, 0x40,
350         0x22, 0x00,
351         0x23, 0x00,
352         0x24, 0x40,
353         0x25, 0x88,
354         0x30, 0xff,
355         0x31, 0x00,
356         0x32, 0xff,
357         0x33, 0x00,
358         0x34, 0x50,
359         0x35, 0x7f,
360         0x36, 0x00,
361         0x37, 0x20,
362         0x38, 0x00,
363         0x40, 0x1c,
364         0x41, 0xff,
365         0x42, 0x29,
366         0x43, 0x00,
367         0x44, 0xff,
368         0x45, 0x00,
369         0x46, 0x00,
370         0x49, 0x04,
371         0x4a, 0x00,
372         0x4b, 0xf8,
373         0x52, 0x30,
374         0x55, 0xae,
375         0x56, 0x47,
376         0x57, 0xe1,
377         0x58, 0x3a,
378         0x5a, 0x1e,
379         0x5b, 0x34,
380         0x60, 0x00,
381         0x63, 0x00,
382         0x64, 0x00,
383         0x65, 0x00,
384         0x66, 0x00,
385         0x67, 0x00,
386         0x68, 0x00,
387         0x69, 0x00,
388         0x6a, 0x02,
389         0x6b, 0x00,
390         0x70, 0xff,
391         0x71, 0x00,
392         0x72, 0x00,
393         0x73, 0x00,
394         0x74, 0x0c,
395         0x80, 0x00,
396         0x81, 0x00,
397         0x82, 0x00,
398         0x83, 0x00,
399         0x84, 0x04,
400         0x85, 0x80,
401         0x86, 0x24,
402         0x87, 0x78,
403         0x88, 0x10,
404         0x89, 0x00,
405         0x90, 0x01,
406         0x91, 0x01,
407         0xa0, 0x04,
408         0xa1, 0x00,
409         0xa2, 0x00,
410         0xb0, 0x91,
411         0xb1, 0x0b,
412         0xc0, 0x53,
413         0xc1, 0x70,
414         0xc2, 0x12,
415         0xd0, 0x00,
416         0xd1, 0x00,
417         0xd2, 0x00,
418         0xd3, 0x00,
419         0xd4, 0x00,
420         0xd5, 0x00,
421         0xde, 0x00,
422         0xdf, 0x00,
423         0x61, 0x49,
424         0x62, 0x0b,
425         0x53, 0x08,
426         0x59, 0x08,
427         0xff, 0xff,
428 };
429
430 static struct stv0297_config alps_tdee4_stv0297_config = {
431         .demod_address = 0x1c,
432         .inittab = alps_tdee4_stv0297_inittab,
433 //      .invert = 1,
434 //      .pll_set = alps_tdee4_stv0297_pll_set,
435 };
436
437 /* try to figure out the frontend, each card/box can have on of the following list */
438 int flexcop_frontend_init(struct flexcop_device *fc)
439 {
440         /* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */
441         if ((fc->fe = stv0299_attach(&samsung_tbmu24112_config, &fc->i2c_adap)) != NULL) {
442                 fc->fe->ops->set_voltage = flexcop_set_voltage;
443
444                 fc->fe_sleep             = fc->fe->ops->sleep;
445                 fc->fe->ops->sleep       = flexcop_sleep;
446
447                 fc->dev_type          = FC_SKY;
448                 info("found the stv0299 at i2c address: 0x%02x",samsung_tbmu24112_config.demod_address);
449         } else
450         /* try the air dvb-t (mt352/Samsung tdtc9251dh0(??)) */
451         if ((fc->fe = mt352_attach(&samsung_tdtc9251dh0_config, &fc->i2c_adap)) != NULL ) {
452                 fc->dev_type          = FC_AIR_DVB;
453                 info("found the mt352 at i2c address: 0x%02x",samsung_tdtc9251dh0_config.demod_address);
454         } else
455         /* try the air atsc 2nd generation (nxt2002) */
456         if ((fc->fe = nxt2002_attach(&samsung_tbmv_config, &fc->i2c_adap)) != NULL) {
457                 fc->dev_type          = FC_AIR_ATSC2;
458                 info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address);
459         } else
460         /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */
461         if ((fc->fe = bcm3510_attach(&air2pc_atsc_first_gen_config, &fc->i2c_adap)) != NULL) {
462                 fc->dev_type          = FC_AIR_ATSC1;
463                 info("found the bcm3510 at i2c address: 0x%02x",air2pc_atsc_first_gen_config.demod_address);
464         } else
465         /* try the cable dvb (stv0297) */
466         if ((fc->fe = stv0297_attach(&alps_tdee4_stv0297_config, &fc->i2c_adap)) != NULL) {
467                 fc->dev_type                        = FC_CABLE;
468                 info("found the stv0297 at i2c address: 0x%02x",alps_tdee4_stv0297_config.demod_address);
469         } else
470         /* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */
471         if ((fc->fe = vp310_attach(&skystar23_samsung_tbdu18132_config, &fc->i2c_adap)) != NULL) {
472                 fc->fe->ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
473                 fc->fe->ops->diseqc_send_burst      = flexcop_diseqc_send_burst;
474                 fc->fe->ops->set_tone               = flexcop_set_tone;
475                 fc->fe->ops->set_voltage            = flexcop_set_voltage;
476
477                 fc->fe_sleep                        = fc->fe->ops->sleep;
478                 fc->fe->ops->sleep                  = flexcop_sleep;
479
480                 fc->dev_type                        = FC_SKY_OLD;
481                 info("found the vp310 (aka mt312) at i2c address: 0x%02x",skystar23_samsung_tbdu18132_config.demod_address);
482         }
483
484         if (fc->fe == NULL) {
485                 err("no frontend driver found for this B2C2/FlexCop adapter");
486                 return -ENODEV;
487         } else {
488                 if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) {
489                         err("frontend registration failed!");
490                         if (fc->fe->ops->release != NULL)
491                                 fc->fe->ops->release(fc->fe);
492                         fc->fe = NULL;
493                         return -EINVAL;
494                 }
495         }
496         fc->init_state |= FC_STATE_FE_INIT;
497         return 0;
498 }
499
500 void flexcop_frontend_exit(struct flexcop_device *fc)
501 {
502         if (fc->init_state & FC_STATE_FE_INIT)
503                 dvb_unregister_frontend(fc->fe);
504
505         fc->init_state &= ~FC_STATE_FE_INIT;
506 }