ehea: Fix napi list corruption on ifconfig down
[cascardo/linux.git] / drivers / media / dvb / b2c2 / flexcop-fe-tuner.c
1 /*
2  * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
3  * flexcop-fe-tuner.c - methods for frontend attachment and DiSEqC controlling
4  * see flexcop.c for copyright information
5  */
6 #include <media/tuner.h>
7 #include "flexcop.h"
8 #include "mt312.h"
9 #include "stv0299.h"
10 #include "s5h1420.h"
11 #include "itd1000.h"
12 #include "cx24113.h"
13 #include "cx24123.h"
14 #include "isl6421.h"
15 #include "mt352.h"
16 #include "bcm3510.h"
17 #include "nxt200x.h"
18 #include "dvb-pll.h"
19 #include "lgdt330x.h"
20 #include "tuner-simple.h"
21 #include "stv0297.h"
22
23 /* lnb control */
24 #if defined(CONFIG_DVB_MT312_MODULE) || defined(CONFIG_DVB_STV0299_MODULE)
25 static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
26 {
27         struct flexcop_device *fc = fe->dvb->priv;
28         flexcop_ibi_value v;
29         deb_tuner("polarity/voltage = %u\n", voltage);
30
31         v = fc->read_ibi_reg(fc, misc_204);
32         switch (voltage) {
33         case SEC_VOLTAGE_OFF:
34                 v.misc_204.ACPI1_sig = 1;
35                 break;
36         case SEC_VOLTAGE_13:
37                 v.misc_204.ACPI1_sig = 0;
38                 v.misc_204.LNB_L_H_sig = 0;
39                 break;
40         case SEC_VOLTAGE_18:
41                 v.misc_204.ACPI1_sig = 0;
42                 v.misc_204.LNB_L_H_sig = 1;
43                 break;
44         default:
45                 err("unknown SEC_VOLTAGE value");
46                 return -EINVAL;
47         }
48         return fc->write_ibi_reg(fc, misc_204, v);
49 }
50 #endif
51
52 #if defined(CONFIG_DVB_S5H1420_MODULE) || defined(CONFIG_DVB_STV0299_MODULE) \
53         || defined(CONFIG_DVB_MT312_MODULE)
54 static int flexcop_sleep(struct dvb_frontend* fe)
55 {
56         struct flexcop_device *fc = fe->dvb->priv;
57         if (fc->fe_sleep)
58                 return fc->fe_sleep(fe);
59         return 0;
60 }
61 #endif
62
63 /* SkyStar2 DVB-S rev 2.3 */
64 #if defined(CONFIG_DVB_MT312_MODULE)
65 static int flexcop_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
66 {
67 /* u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc }; */
68         struct flexcop_device *fc = fe->dvb->priv;
69         flexcop_ibi_value v;
70         u16 ax;
71         v.raw = 0;
72         deb_tuner("tone = %u\n",tone);
73
74         switch (tone) {
75         case SEC_TONE_ON:
76                 ax = 0x01ff;
77                 break;
78         case SEC_TONE_OFF:
79                 ax = 0;
80                 break;
81         default:
82                 err("unknown SEC_TONE value");
83                 return -EINVAL;
84         }
85
86         v.lnb_switch_freq_200.LNB_CTLPrescaler_sig = 1; /* divide by 2 */
87         v.lnb_switch_freq_200.LNB_CTLHighCount_sig = ax;
88         v.lnb_switch_freq_200.LNB_CTLLowCount_sig  = ax == 0 ? 0x1ff : ax;
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         for (i = 7; i >= 0; i--) {
104                 d = (data >> i) & 1;
105                 par ^= d;
106                 flexcop_diseqc_send_bit(fe, d);
107         }
108         flexcop_diseqc_send_bit(fe, par);
109 }
110
111 static int flexcop_send_diseqc_msg(struct dvb_frontend *fe,
112         int len, u8 *msg, unsigned long burst)
113 {
114         int i;
115
116         flexcop_set_tone(fe, SEC_TONE_OFF);
117         mdelay(16);
118
119         for (i = 0; i < len; i++)
120                 flexcop_diseqc_send_byte(fe,msg[i]);
121         mdelay(16);
122
123         if (burst != -1) {
124                 if (burst)
125                         flexcop_diseqc_send_byte(fe, 0xff);
126                 else {
127                         flexcop_set_tone(fe, SEC_TONE_ON);
128                         mdelay(12);
129                         udelay(500);
130                         flexcop_set_tone(fe, SEC_TONE_OFF);
131                 }
132                 msleep(20);
133         }
134         return 0;
135 }
136
137 static int flexcop_diseqc_send_master_cmd(struct dvb_frontend *fe,
138         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,
144         fe_sec_mini_cmd_t minicmd)
145 {
146         return flexcop_send_diseqc_msg(fe, 0, NULL, minicmd);
147 }
148
149 static struct mt312_config skystar23_samsung_tbdu18132_config = {
150         .demod_address = 0x0e,
151 };
152
153 static int skystar23_samsung_tbdu18132_tuner_set_params(struct dvb_frontend *fe,
154         struct dvb_frontend_parameters *params)
155 {
156         u8 buf[4];
157         u32 div;
158         struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf,
159         .len = sizeof(buf) };
160         struct flexcop_device *fc = fe->dvb->priv;
161         div = (params->frequency + (125/2)) / 125;
162
163         buf[0] = (div >> 8) & 0x7f;
164         buf[1] = (div >> 0) & 0xff;
165         buf[2] = 0x84 | ((div >> 10) & 0x60);
166         buf[3] = 0x80;
167
168         if (params->frequency < 1550000)
169                 buf[3] |= 0x02;
170
171         if (fe->ops.i2c_gate_ctrl)
172                 fe->ops.i2c_gate_ctrl(fe, 1);
173         if (i2c_transfer(&fc->fc_i2c_adap[0].i2c_adap, &msg, 1) != 1)
174                 return -EIO;
175         return 0;
176 }
177
178 static int skystar2_rev23_attach(struct flexcop_device *fc,
179         struct i2c_adapter *i2c)
180 {
181         fc->fe = dvb_attach(mt312_attach, &skystar23_samsung_tbdu18132_config, i2c);
182         if (fc->fe != NULL) {
183                 struct dvb_frontend_ops *ops = &fc->fe->ops;
184                 ops->tuner_ops.set_params   =
185                         skystar23_samsung_tbdu18132_tuner_set_params;
186                 ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
187                 ops->diseqc_send_burst      = flexcop_diseqc_send_burst;
188                 ops->set_tone               = flexcop_set_tone;
189                 ops->set_voltage            = flexcop_set_voltage;
190                 fc->fe_sleep                = ops->sleep;
191                 ops->sleep                  = flexcop_sleep;
192                 return 1;
193         }
194         return 0;
195 }
196 #endif
197
198 /* SkyStar2 DVB-S rev 2.6 */
199 #if defined(CONFIG_DVB_STV0299_MODULE)
200 static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend *fe,
201         u32 srate, u32 ratio)
202 {
203         u8 aclk = 0;
204         u8 bclk = 0;
205
206         if (srate < 1500000) {
207                 aclk = 0xb7; bclk = 0x47;
208         } else if (srate < 3000000) {
209                 aclk = 0xb7; bclk = 0x4b;
210         } else if (srate < 7000000) {
211                 aclk = 0xb7; bclk = 0x4f;
212         } else if (srate < 14000000) {
213                 aclk = 0xb7; bclk = 0x53;
214         } else if (srate < 30000000) {
215                 aclk = 0xb6; bclk = 0x53;
216         } else if (srate < 45000000) {
217                 aclk = 0xb4; bclk = 0x51;
218         }
219
220         stv0299_writereg(fe, 0x13, aclk);
221         stv0299_writereg(fe, 0x14, bclk);
222         stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
223         stv0299_writereg(fe, 0x20, (ratio >>  8) & 0xff);
224         stv0299_writereg(fe, 0x21,  ratio        & 0xf0);
225         return 0;
226 }
227
228 static int samsung_tbmu24112_tuner_set_params(struct dvb_frontend *fe,
229         struct dvb_frontend_parameters *params)
230 {
231         u8 buf[4];
232         u32 div;
233         struct i2c_msg msg = {
234         .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
235         struct flexcop_device *fc = fe->dvb->priv;
236         div = params->frequency / 125;
237
238         buf[0] = (div >> 8) & 0x7f;
239         buf[1] = div & 0xff;
240         buf[2] = 0x84; /* 0xC4 */
241         buf[3] = 0x08;
242
243         if (params->frequency < 1500000)
244                 buf[3] |= 0x10;
245
246         if (fe->ops.i2c_gate_ctrl)
247                 fe->ops.i2c_gate_ctrl(fe, 1);
248         if (i2c_transfer(&fc->fc_i2c_adap[0].i2c_adap, &msg, 1) != 1)
249                 return -EIO;
250         return 0;
251 }
252
253 static u8 samsung_tbmu24112_inittab[] = {
254         0x01, 0x15,
255         0x02, 0x30,
256         0x03, 0x00,
257         0x04, 0x7D,
258         0x05, 0x35,
259         0x06, 0x02,
260         0x07, 0x00,
261         0x08, 0xC3,
262         0x0C, 0x00,
263         0x0D, 0x81,
264         0x0E, 0x23,
265         0x0F, 0x12,
266         0x10, 0x7E,
267         0x11, 0x84,
268         0x12, 0xB9,
269         0x13, 0x88,
270         0x14, 0x89,
271         0x15, 0xC9,
272         0x16, 0x00,
273         0x17, 0x5C,
274         0x18, 0x00,
275         0x19, 0x00,
276         0x1A, 0x00,
277         0x1C, 0x00,
278         0x1D, 0x00,
279         0x1E, 0x00,
280         0x1F, 0x3A,
281         0x20, 0x2E,
282         0x21, 0x80,
283         0x22, 0xFF,
284         0x23, 0xC1,
285         0x28, 0x00,
286         0x29, 0x1E,
287         0x2A, 0x14,
288         0x2B, 0x0F,
289         0x2C, 0x09,
290         0x2D, 0x05,
291         0x31, 0x1F,
292         0x32, 0x19,
293         0x33, 0xFE,
294         0x34, 0x93,
295         0xff, 0xff,
296 };
297
298 static struct stv0299_config samsung_tbmu24112_config = {
299         .demod_address = 0x68,
300         .inittab = samsung_tbmu24112_inittab,
301         .mclk = 88000000UL,
302         .invert = 0,
303         .skip_reinit = 0,
304         .lock_output = STV0299_LOCKOUTPUT_LK,
305         .volt13_op0_op1 = STV0299_VOLT13_OP1,
306         .min_delay_ms = 100,
307         .set_symbol_rate = samsung_tbmu24112_set_symbol_rate,
308 };
309
310 static int skystar2_rev26_attach(struct flexcop_device *fc,
311         struct i2c_adapter *i2c)
312 {
313         fc->fe = dvb_attach(stv0299_attach, &samsung_tbmu24112_config, i2c);
314         if (fc->fe != NULL) {
315                 struct dvb_frontend_ops *ops  = &fc->fe->ops;
316                 ops->tuner_ops.set_params = samsung_tbmu24112_tuner_set_params;
317                 ops->set_voltage = flexcop_set_voltage;
318                 fc->fe_sleep = ops->sleep;
319                 ops->sleep = flexcop_sleep;
320                 return 1;
321         }
322         return 0;
323 }
324 #endif
325
326 /* SkyStar2 DVB-S rev 2.7 */
327 #if defined(CONFIG_DVB_S5H1420_MODULE)
328 static struct s5h1420_config skystar2_rev2_7_s5h1420_config = {
329         .demod_address = 0x53,
330         .invert = 1,
331         .repeated_start_workaround = 1,
332         .serial_mpeg = 1,
333 };
334
335 static struct itd1000_config skystar2_rev2_7_itd1000_config = {
336         .i2c_address = 0x61,
337 };
338
339 static int skystar2_rev27_attach(struct flexcop_device *fc,
340         struct i2c_adapter *i2c)
341 {
342         flexcop_ibi_value r108;
343         struct i2c_adapter *i2c_tuner;
344
345         /* enable no_base_addr - no repeated start when reading */
346         fc->fc_i2c_adap[0].no_base_addr = 1;
347         fc->fe = dvb_attach(s5h1420_attach, &skystar2_rev2_7_s5h1420_config,
348                             i2c);
349         if (!fc->fe)
350                 goto fail;
351
352         i2c_tuner = s5h1420_get_tuner_i2c_adapter(fc->fe);
353         if (!i2c_tuner)
354                 goto fail;
355
356         fc->fe_sleep = fc->fe->ops.sleep;
357         fc->fe->ops.sleep = flexcop_sleep;
358
359         /* enable no_base_addr - no repeated start when reading */
360         fc->fc_i2c_adap[2].no_base_addr = 1;
361         if (!dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap,
362                         0x08, 1, 1)) {
363                 err("ISL6421 could NOT be attached");
364                 goto fail_isl;
365         }
366         info("ISL6421 successfully attached");
367
368         /* the ITD1000 requires a lower i2c clock - is it a problem ? */
369         r108.raw = 0x00000506;
370         fc->write_ibi_reg(fc, tw_sm_c_108, r108);
371         if (!dvb_attach(itd1000_attach, fc->fe, i2c_tuner,
372                         &skystar2_rev2_7_itd1000_config)) {
373                 err("ITD1000 could NOT be attached");
374                 /* Should i2c clock be restored? */
375                 goto fail_isl;
376         }
377         info("ITD1000 successfully attached");
378
379         return 1;
380
381 fail_isl:
382         fc->fc_i2c_adap[2].no_base_addr = 0;
383 fail:
384         /* for the next devices we need it again */
385         fc->fc_i2c_adap[0].no_base_addr = 0;
386         return 0;
387 }
388 #endif
389
390 /* SkyStar2 rev 2.8 */
391 #if defined(CONFIG_DVB_CX24123_MODULE)
392 static struct cx24123_config skystar2_rev2_8_cx24123_config = {
393         .demod_address = 0x55,
394         .dont_use_pll = 1,
395         .agc_callback = cx24113_agc_callback,
396 };
397
398 static const struct cx24113_config skystar2_rev2_8_cx24113_config = {
399         .i2c_addr = 0x54,
400         .xtal_khz = 10111,
401 };
402
403 static int skystar2_rev28_attach(struct flexcop_device *fc,
404         struct i2c_adapter *i2c)
405 {
406         struct i2c_adapter *i2c_tuner;
407
408         fc->fe = dvb_attach(cx24123_attach, &skystar2_rev2_8_cx24123_config,
409                             i2c);
410         if (!fc->fe)
411                 return 0;
412
413         i2c_tuner = cx24123_get_tuner_i2c_adapter(fc->fe);;
414         if (!i2c_tuner)
415                 return 0;
416
417         if (!dvb_attach(cx24113_attach, fc->fe, &skystar2_rev2_8_cx24113_config,
418                         i2c_tuner)) {
419                 err("CX24113 could NOT be attached");
420                 return 0;
421         }
422         info("CX24113 successfully attached");
423
424         fc->fc_i2c_adap[2].no_base_addr = 1;
425         if (!dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap,
426                         0x08, 0, 0)) {
427                 err("ISL6421 could NOT be attached");
428                 fc->fc_i2c_adap[2].no_base_addr = 0;
429                 return 0;
430         }
431         info("ISL6421 successfully attached");
432         /* TODO on i2c_adap[1] addr 0x11 (EEPROM) there seems to be an
433          * IR-receiver (PIC16F818) - but the card has no input for that ??? */
434         return 1;
435 }
436 #endif
437
438 /* AirStar DVB-T */
439 #if defined(CONFIG_DVB_MT352_MODULE)
440 static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend *fe)
441 {
442         static u8 mt352_clock_config[] = { 0x89, 0x18, 0x2d };
443         static u8 mt352_reset[] = { 0x50, 0x80 };
444         static u8 mt352_adc_ctl_1_cfg[] = { 0x8E, 0x40 };
445         static u8 mt352_agc_cfg[] = { 0x67, 0x28, 0xa1 };
446         static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
447
448         mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
449         udelay(2000);
450         mt352_write(fe, mt352_reset, sizeof(mt352_reset));
451         mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
452         mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
453         mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
454         return 0;
455 }
456
457 static int samsung_tdtc9251dh0_calc_regs(struct dvb_frontend *fe,
458         struct dvb_frontend_parameters *params, u8* pllbuf, int buf_len)
459 {
460         u32 div;
461         unsigned char bs = 0;
462
463         if (buf_len < 5)
464                 return -EINVAL;
465
466 #define IF_FREQUENCYx6 217    /* 6 * 36.16666666667MHz */
467         div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
468         if (params->frequency >= 48000000 && params->frequency <= 154000000) \
469                 bs = 0x09;
470         if (params->frequency >= 161000000 && params->frequency <= 439000000) \
471                 bs = 0x0a;
472         if (params->frequency >= 447000000 && params->frequency <= 863000000) \
473                 bs = 0x08;
474
475         pllbuf[0] = 0x61;
476         pllbuf[1] = div >> 8;
477         pllbuf[2] = div & 0xff;
478         pllbuf[3] = 0xcc;
479         pllbuf[4] = bs;
480         return 5;
481 }
482
483 static struct mt352_config samsung_tdtc9251dh0_config = {
484         .demod_address = 0x0f,
485         .demod_init    = samsung_tdtc9251dh0_demod_init,
486 };
487
488 static int airstar_dvbt_attach(struct flexcop_device *fc,
489         struct i2c_adapter *i2c)
490 {
491         fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, i2c);
492         if (fc->fe != NULL) {
493                 fc->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs;
494                 return 1;
495         }
496         return 0;
497 }
498 #endif
499
500 /* AirStar ATSC 1st generation */
501 #if defined(CONFIG_DVB_BCM3510_MODULE)
502 static int flexcop_fe_request_firmware(struct dvb_frontend *fe,
503         const struct firmware **fw, char* name)
504 {
505         struct flexcop_device *fc = fe->dvb->priv;
506         return request_firmware(fw, name, fc->dev);
507 }
508
509 static struct bcm3510_config air2pc_atsc_first_gen_config = {
510         .demod_address    = 0x0f,
511         .request_firmware = flexcop_fe_request_firmware,
512 };
513
514 static int airstar_atsc1_attach(struct flexcop_device *fc,
515         struct i2c_adapter *i2c)
516 {
517         fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, i2c);
518         return fc->fe != NULL;
519 }
520 #endif
521
522 /* AirStar ATSC 2nd generation */
523 #if defined(CONFIG_DVB_NXT200X_MODULE)
524 static struct nxt200x_config samsung_tbmv_config = {
525         .demod_address = 0x0a,
526 };
527
528 static int airstar_atsc2_attach(struct flexcop_device *fc,
529         struct i2c_adapter *i2c)
530 {
531         fc->fe = dvb_attach(nxt200x_attach, &samsung_tbmv_config, i2c);
532         if (!fc->fe)
533                 return 0;
534
535         return !!dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL,
536                             DVB_PLL_SAMSUNG_TBMV);
537 }
538 #endif
539
540 /* AirStar ATSC 3rd generation */
541 #if defined(CONFIG_DVB_LGDT330X_MODULE)
542 static struct lgdt330x_config air2pc_atsc_hd5000_config = {
543         .demod_address       = 0x59,
544         .demod_chip          = LGDT3303,
545         .serial_mpeg         = 0x04,
546         .clock_polarity_flip = 1,
547 };
548
549 static int airstar_atsc3_attach(struct flexcop_device *fc,
550         struct i2c_adapter *i2c)
551 {
552         fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, i2c);
553         if (!fc->fe)
554                 return 0;
555
556         return !!dvb_attach(simple_tuner_attach, fc->fe, i2c, 0x61,
557                             TUNER_LG_TDVS_H06XF);
558 }
559 #endif
560
561 /* CableStar2 DVB-C */
562 #if defined(CONFIG_DVB_STV0297_MODULE)
563 static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe,
564                 struct dvb_frontend_parameters *fep)
565 {
566         struct flexcop_device *fc = fe->dvb->priv;
567         u8 buf[4];
568         u16 div;
569         int ret;
570
571 /* 62.5 kHz * 10 */
572 #define REF_FREQ    625
573 #define FREQ_OFFSET 36125
574
575         div = ((fep->frequency/1000 + FREQ_OFFSET) * 10) / REF_FREQ;
576 /* 4 MHz = 4000 KHz */
577
578         buf[0] = (u8)( div >> 8) & 0x7f;
579         buf[1] = (u8)        div & 0xff;
580
581 /* F(osc) = N * Reference Freq. (62.5 kHz)
582  * byte 2 :  0 N14 N13 N12 N11 N10 N9  N8
583  * byte 3 : N7 N6  N5  N4  N3  N2  N1  N0
584  * byte 4 : 1  *   *   AGD R3  R2  R1  R0
585  * byte 5 : C1 *   RE  RTS BS4 BS3 BS2 BS1
586  * AGD = 1, R3 R2 R1 R0 = 0 1 0 1 => byte 4 = 1**10101 = 0x95 */
587         buf[2] = 0x95;
588
589 /* Range(MHz)  C1 *  RE RTS BS4 BS3 BS2 BS1  Byte 5
590  *  47 - 153   0  *  0   0   0   0   0   1   0x01
591  * 153 - 430   0  *  0   0   0   0   1   0   0x02
592  * 430 - 822   0  *  0   0   1   0   0   0   0x08
593  * 822 - 862   1  *  0   0   1   0   0   0   0x88 */
594
595              if (fep->frequency <= 153000000) buf[3] = 0x01;
596         else if (fep->frequency <= 430000000) buf[3] = 0x02;
597         else if (fep->frequency <= 822000000) buf[3] = 0x08;
598         else buf[3] = 0x88;
599
600         if (fe->ops.i2c_gate_ctrl)
601                 fe->ops.i2c_gate_ctrl(fe, 0);
602         deb_tuner("tuner buffer for %d Hz: %x %x %x %x\n", fep->frequency,
603         buf[0], buf[1], buf[2], buf[3]);
604         ret = fc->i2c_request(&fc->fc_i2c_adap[2],
605                         FC_WRITE, 0x61, buf[0], &buf[1], 3);
606         deb_tuner("tuner write returned: %d\n",ret);
607         return ret;
608 }
609
610 static u8 alps_tdee4_stv0297_inittab[] = {
611         0x80, 0x01,
612         0x80, 0x00,
613         0x81, 0x01,
614         0x81, 0x00,
615         0x00, 0x48,
616         0x01, 0x58,
617         0x03, 0x00,
618         0x04, 0x00,
619         0x07, 0x00,
620         0x08, 0x00,
621         0x30, 0xff,
622         0x31, 0x9d,
623         0x32, 0xff,
624         0x33, 0x00,
625         0x34, 0x29,
626         0x35, 0x55,
627         0x36, 0x80,
628         0x37, 0x6e,
629         0x38, 0x9c,
630         0x40, 0x1a,
631         0x41, 0xfe,
632         0x42, 0x33,
633         0x43, 0x00,
634         0x44, 0xff,
635         0x45, 0x00,
636         0x46, 0x00,
637         0x49, 0x04,
638         0x4a, 0x51,
639         0x4b, 0xf8,
640         0x52, 0x30,
641         0x53, 0x06,
642         0x59, 0x06,
643         0x5a, 0x5e,
644         0x5b, 0x04,
645         0x61, 0x49,
646         0x62, 0x0a,
647         0x70, 0xff,
648         0x71, 0x04,
649         0x72, 0x00,
650         0x73, 0x00,
651         0x74, 0x0c,
652         0x80, 0x20,
653         0x81, 0x00,
654         0x82, 0x30,
655         0x83, 0x00,
656         0x84, 0x04,
657         0x85, 0x22,
658         0x86, 0x08,
659         0x87, 0x1b,
660         0x88, 0x00,
661         0x89, 0x00,
662         0x90, 0x00,
663         0x91, 0x04,
664         0xa0, 0x86,
665         0xa1, 0x00,
666         0xa2, 0x00,
667         0xb0, 0x91,
668         0xb1, 0x0b,
669         0xc0, 0x5b,
670         0xc1, 0x10,
671         0xc2, 0x12,
672         0xd0, 0x02,
673         0xd1, 0x00,
674         0xd2, 0x00,
675         0xd3, 0x00,
676         0xd4, 0x02,
677         0xd5, 0x00,
678         0xde, 0x00,
679         0xdf, 0x01,
680         0xff, 0xff,
681 };
682
683 static struct stv0297_config alps_tdee4_stv0297_config = {
684         .demod_address = 0x1c,
685         .inittab = alps_tdee4_stv0297_inittab,
686 };
687
688 static int cablestar2_attach(struct flexcop_device *fc,
689         struct i2c_adapter *i2c)
690 {
691         fc->fc_i2c_adap[0].no_base_addr = 1;
692         fc->fe = dvb_attach(stv0297_attach, &alps_tdee4_stv0297_config, i2c);
693         if (!fc->fe) {
694                 /* Reset for next frontend to try */
695                 fc->fc_i2c_adap[0].no_base_addr = 0;
696                 return 0;
697         }
698         fc->fe->ops.tuner_ops.set_params = alps_tdee4_stv0297_tuner_set_params;
699         return 1;
700 }
701 #endif
702
703 static struct {
704         flexcop_device_type_t type;
705         int (*attach)(struct flexcop_device *, struct i2c_adapter *);
706 } flexcop_frontends[] = {
707 #if defined(CONFIG_DVB_S5H1420_MODULE)
708         { FC_SKY_REV27, skystar2_rev27_attach },
709 #endif
710 #if defined(CONFIG_DVB_CX24123_MODULE)
711         { FC_SKY_REV28, skystar2_rev28_attach },
712 #endif
713 #if defined(CONFIG_DVB_STV0299_MODULE)
714         { FC_SKY_REV26, skystar2_rev26_attach },
715 #endif
716 #if defined(CONFIG_DVB_MT352_MODULE)
717         { FC_AIR_DVBT, airstar_dvbt_attach },
718 #endif
719 #if defined(CONFIG_DVB_NXT200X_MODULE)
720         { FC_AIR_ATSC2, airstar_atsc2_attach },
721 #endif
722 #if defined(CONFIG_DVB_LGDT330X_MODULE)
723         { FC_AIR_ATSC3, airstar_atsc3_attach },
724 #endif
725 #if defined(CONFIG_DVB_BCM3510_MODULE)
726         { FC_AIR_ATSC1, airstar_atsc1_attach },
727 #endif
728 #if defined(CONFIG_DVB_STV0297_MODULE)
729         { FC_CABLE, cablestar2_attach },
730 #endif
731 #if defined(CONFIG_DVB_MT312_MODULE)
732         { FC_SKY_REV23, skystar2_rev23_attach },
733 #endif
734 };
735
736 /* try to figure out the frontend */
737 int flexcop_frontend_init(struct flexcop_device *fc)
738 {
739         int i;
740         for (i = 0; i < ARRAY_SIZE(flexcop_frontends); i++) {
741                 /* type needs to be set before, because of some workarounds
742                  * done based on the probed card type */
743                 fc->dev_type = flexcop_frontends[i].type;
744                 if (flexcop_frontends[i].attach(fc, &fc->fc_i2c_adap[0].i2c_adap))
745                         goto fe_found;
746                 /* Clean up partially attached frontend */
747                 if (fc->fe) {
748                         dvb_frontend_detach(fc->fe);
749                         fc->fe = NULL;
750                 }
751         }
752         fc->dev_type = FC_UNK;
753         err("no frontend driver found for this B2C2/FlexCop adapter");
754         return -ENODEV;
755
756 fe_found:
757         info("found '%s' .", fc->fe->ops.info.name);
758         if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) {
759                 err("frontend registration failed!");
760                 dvb_frontend_detach(fc->fe);
761                 fc->fe = NULL;
762                 return -EINVAL;
763         }
764         fc->init_state |= FC_STATE_FE_INIT;
765         return 0;
766 }
767
768 void flexcop_frontend_exit(struct flexcop_device *fc)
769 {
770         if (fc->init_state & FC_STATE_FE_INIT) {
771                 dvb_unregister_frontend(fc->fe);
772                 dvb_frontend_detach(fc->fe);
773         }
774         fc->init_state &= ~FC_STATE_FE_INIT;
775 }