blob: 89ea76201506aa050bf5ac38680025875746c425 [file] [log] [blame]
Johannes Stezenbach2add87a2005-05-16 21:54:10 -07001/*
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"
Michael Krufky46365f32006-01-23 09:52:39 -020012#include "nxt200x.h"
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -070013#include "bcm3510.h"
Johannes Stezenbach2add87a2005-05-16 21:54:10 -070014#include "stv0297.h"
15#include "mt312.h"
Michael Krufkyc0b11b92005-11-08 21:35:32 -080016#include "lgdt330x.h"
Michael Krufky81ad34282006-04-24 23:21:46 -030017#include "lg_h06xf.h"
Michael Krufkyc0b11b92005-11-08 21:35:32 -080018#include "dvb-pll.h"
Johannes Stezenbach2add87a2005-05-16 21:54:10 -070019
20/* lnb control */
21
22static 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
48static 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
62static 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
Johannes Stezenbach958706c2005-05-16 21:54:19 -070086 v.lnb_switch_freq_200.LNB_CTLHighCount_sig = ax;
87 v.lnb_switch_freq_200.LNB_CTLLowCount_sig = ax == 0 ? 0x1ff : ax;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -070088
89 return fc->write_ibi_reg(fc,lnb_switch_freq_200,v);
90}
91
92static 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
100static 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
113static 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
138static 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
143static 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 */
149static 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
Andrew de Quincey56e03142006-04-18 17:47:12 -0300170static int samsung_tbmu24112_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params)
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700171{
172 u8 buf[4];
173 u32 div;
174 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
Andrew de Quincey56e03142006-04-18 17:47:12 -0300175 struct flexcop_device *fc = fe->dvb->priv;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700176
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
Andrew de Quincey56e03142006-04-18 17:47:12 -0300186 if (fe->ops->i2c_gate_ctrl)
187 fe->ops->i2c_gate_ctrl(fe, 1);
188 if (i2c_transfer(&fc->i2c_adap, &msg, 1) != 1) {
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700189 return -EIO;
Andrew de Quincey56e03142006-04-18 17:47:12 -0300190 }
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700191 return 0;
192}
193
194static 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
239static struct stv0299_config samsung_tbmu24112_config = {
240 .demod_address = 0x68,
241 .inittab = samsung_tbmu24112_inittab,
242 .mclk = 88000000UL,
243 .invert = 0,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700244 .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,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700249};
250
251/* dvb-t mt352 */
252static 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
Andrew de Quincey56e03142006-04-18 17:47:12 -0300271static int samsung_tdtc9251dh0_calc_regs(struct dvb_frontend* fe, struct dvb_frontend_parameters *params, u8* pllbuf, int buf_len)
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700272{
273 u32 div;
274 unsigned char bs = 0;
275
Andrew de Quincey56e03142006-04-18 17:47:12 -0300276 if (buf_len < 5)
277 return -EINVAL;
278
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700279 #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
Andrew de Quincey56e03142006-04-18 17:47:12 -0300286 pllbuf[0] = 0x61;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700287 pllbuf[1] = div >> 8;
288 pllbuf[2] = div & 0xff;
289 pllbuf[3] = 0xcc;
290 pllbuf[4] = bs;
291
Andrew de Quincey56e03142006-04-18 17:47:12 -0300292 return 5;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700293}
294
295static struct mt352_config samsung_tdtc9251dh0_config = {
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700296 .demod_address = 0x0f,
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700297 .demod_init = samsung_tdtc9251dh0_demod_init,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700298};
299
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700300static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700301{
302 struct flexcop_device *fc = fe->dvb->priv;
303 return request_firmware(fw, name, fc->dev);
304}
305
Andrew de Quincey56e03142006-04-18 17:47:12 -0300306static int lgdt3303_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params)
Michael Krufkyc0b11b92005-11-08 21:35:32 -0800307{
308 struct flexcop_device *fc = fe->dvb->priv;
Michael Krufky7c250392006-04-18 17:47:08 -0300309 return lg_h06xf_pll_set(fe, &fc->i2c_adap, params);
Michael Krufkyc0b11b92005-11-08 21:35:32 -0800310}
311
312static struct lgdt330x_config air2pc_atsc_hd5000_config = {
313 .demod_address = 0x59,
314 .demod_chip = LGDT3303,
315 .serial_mpeg = 0x04,
Michael Krufkyc0b11b92005-11-08 21:35:32 -0800316 .clock_polarity_flip = 1,
317};
318
Michael Krufky46365f32006-01-23 09:52:39 -0200319static struct nxt200x_config samsung_tbmv_config = {
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700320 .demod_address = 0x0a,
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700321};
322
323static struct bcm3510_config air2pc_atsc_first_gen_config = {
324 .demod_address = 0x0f,
325 .request_firmware = flexcop_fe_request_firmware,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700326};
327
Andrew de Quincey56e03142006-04-18 17:47:12 -0300328static int skystar23_samsung_tbdu18132_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params)
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700329{
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
Andrew de Quincey56e03142006-04-18 17:47:12 -0300345 if (fe->ops->i2c_gate_ctrl)
346 fe->ops->i2c_gate_ctrl(fe, 1);
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700347 if (i2c_transfer(&fc->i2c_adap, &msg, 1) != 1)
348 return -EIO;
349 return 0;
350}
351
352static struct mt312_config skystar23_samsung_tbdu18132_config = {
353
354 .demod_address = 0x0e,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700355};
356
Andrew de Quincey56e03142006-04-18 17:47:12 -0300357int alps_tdee4_stv0297_tuner_set_params (struct dvb_frontend* fe, struct dvb_frontend_parameters *fep)
358{
359 struct flexcop_device *fc = fe->dvb->priv;
360 u8 buf[4];
361 u16 div;
362 int ret;
363
364/* 62.5 kHz * 10 */
365#define REF_FREQ 625
366#define FREQ_OFFSET 36125
367
368 div = ((fep->frequency/1000 + FREQ_OFFSET ) * 10) / REF_FREQ; // 4 MHz = 4000 KHz
369
370 buf[0] = (u8)( div >> 8) & 0x7f;
371 buf[1] = (u8) div & 0xff;
372
373/* F(osc) = N * Reference Freq. (62.5 kHz)
374 * byte 2 : 0 N14 N13 N12 N11 N10 N9 N8
375 * byte 3 : N7 N6 N5 N4 N3 N2 N1 N0
376 * byte 4 : 1 * * AGD R3 R2 R1 R0
377 * byte 5 : C1 * RE RTS BS4 BS3 BS2 BS1
378 * AGD = 1, R3 R2 R1 R0 = 0 1 0 1 => byte 4 = 1**10101 = 0x95 */
379 buf[2] = 0x95;
380
381// Range(MHz) C1 * RE RTS BS4 BS3 BS2 BS1 Byte 5
382// 47 - 153 0 * 0 0 0 0 0 1 0x01
383// 153 - 430 0 * 0 0 0 0 1 0 0x02
384// 430 - 822 0 * 0 0 1 0 0 0 0x08
385// 822 - 862 1 * 0 0 1 0 0 0 0x88
386
387 if (fep->frequency <= 153000000) buf[3] = 0x01;
388 else if (fep->frequency <= 430000000) buf[3] = 0x02;
389 else if (fep->frequency <= 822000000) buf[3] = 0x08;
390 else buf[3] = 0x88;
391
392 if (fe->ops->i2c_gate_ctrl)
393 fe->ops->i2c_gate_ctrl(fe, 1);
394 deb_tuner("tuner buffer for %d Hz: %x %x %x %x\n",fep->frequency, buf[0],buf[1],buf[2],buf[3]);
395 ret = fc->i2c_request(fc,FC_WRITE,FC_I2C_PORT_TUNER,0x61,buf[0],&buf[1],3);
396 deb_tuner("tuner write returned: %d\n",ret);
397
398 return 0;
399}
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700400
401static u8 alps_tdee4_stv0297_inittab[] = {
402 0x80, 0x01,
403 0x80, 0x00,
404 0x81, 0x01,
405 0x81, 0x00,
406 0x00, 0x09,
407 0x01, 0x69,
408 0x03, 0x00,
409 0x04, 0x00,
410 0x07, 0x00,
411 0x08, 0x00,
412 0x20, 0x00,
413 0x21, 0x40,
414 0x22, 0x00,
415 0x23, 0x00,
416 0x24, 0x40,
417 0x25, 0x88,
418 0x30, 0xff,
419 0x31, 0x00,
420 0x32, 0xff,
421 0x33, 0x00,
422 0x34, 0x50,
423 0x35, 0x7f,
424 0x36, 0x00,
425 0x37, 0x20,
426 0x38, 0x00,
427 0x40, 0x1c,
428 0x41, 0xff,
429 0x42, 0x29,
430 0x43, 0x00,
431 0x44, 0xff,
432 0x45, 0x00,
433 0x46, 0x00,
434 0x49, 0x04,
435 0x4a, 0x00,
436 0x4b, 0xf8,
437 0x52, 0x30,
438 0x55, 0xae,
439 0x56, 0x47,
440 0x57, 0xe1,
441 0x58, 0x3a,
442 0x5a, 0x1e,
443 0x5b, 0x34,
444 0x60, 0x00,
445 0x63, 0x00,
446 0x64, 0x00,
447 0x65, 0x00,
448 0x66, 0x00,
449 0x67, 0x00,
450 0x68, 0x00,
451 0x69, 0x00,
452 0x6a, 0x02,
453 0x6b, 0x00,
454 0x70, 0xff,
455 0x71, 0x00,
456 0x72, 0x00,
457 0x73, 0x00,
458 0x74, 0x0c,
459 0x80, 0x00,
460 0x81, 0x00,
461 0x82, 0x00,
462 0x83, 0x00,
463 0x84, 0x04,
464 0x85, 0x80,
465 0x86, 0x24,
466 0x87, 0x78,
467 0x88, 0x10,
468 0x89, 0x00,
469 0x90, 0x01,
470 0x91, 0x01,
471 0xa0, 0x04,
472 0xa1, 0x00,
473 0xa2, 0x00,
474 0xb0, 0x91,
475 0xb1, 0x0b,
476 0xc0, 0x53,
477 0xc1, 0x70,
478 0xc2, 0x12,
479 0xd0, 0x00,
480 0xd1, 0x00,
481 0xd2, 0x00,
482 0xd3, 0x00,
483 0xd4, 0x00,
484 0xd5, 0x00,
485 0xde, 0x00,
486 0xdf, 0x00,
487 0x61, 0x49,
488 0x62, 0x0b,
489 0x53, 0x08,
490 0x59, 0x08,
491 0xff, 0xff,
492};
493
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700494static struct stv0297_config alps_tdee4_stv0297_config = {
495 .demod_address = 0x1c,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700496 .inittab = alps_tdee4_stv0297_inittab,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700497// .invert = 1,
498// .pll_set = alps_tdee4_stv0297_pll_set,
499};
500
501/* try to figure out the frontend, each card/box can have on of the following list */
502int flexcop_frontend_init(struct flexcop_device *fc)
503{
Jesper Juhl6a5bdd32006-01-09 15:25:23 -0200504 struct dvb_frontend_ops *ops;
505
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700506 /* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */
507 if ((fc->fe = stv0299_attach(&samsung_tbmu24112_config, &fc->i2c_adap)) != NULL) {
Jesper Juhl6a5bdd32006-01-09 15:25:23 -0200508 ops = fc->fe->ops;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700509
Andrew de Quincey56e03142006-04-18 17:47:12 -0300510 ops->tuner_ops.set_params = samsung_tbmu24112_tuner_set_params;
511
Jesper Juhl6a5bdd32006-01-09 15:25:23 -0200512 ops->set_voltage = flexcop_set_voltage;
513
514 fc->fe_sleep = ops->sleep;
515 ops->sleep = flexcop_sleep;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700516
517 fc->dev_type = FC_SKY;
518 info("found the stv0299 at i2c address: 0x%02x",samsung_tbmu24112_config.demod_address);
519 } else
520 /* try the air dvb-t (mt352/Samsung tdtc9251dh0(??)) */
521 if ((fc->fe = mt352_attach(&samsung_tdtc9251dh0_config, &fc->i2c_adap)) != NULL ) {
522 fc->dev_type = FC_AIR_DVB;
Andrew de Quincey56e03142006-04-18 17:47:12 -0300523 fc->fe->ops->tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700524 info("found the mt352 at i2c address: 0x%02x",samsung_tdtc9251dh0_config.demod_address);
525 } else
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700526 /* try the air atsc 2nd generation (nxt2002) */
Michael Krufky46365f32006-01-23 09:52:39 -0200527 if ((fc->fe = nxt200x_attach(&samsung_tbmv_config, &fc->i2c_adap)) != NULL) {
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700528 fc->dev_type = FC_AIR_ATSC2;
Andrew de Quincey56e03142006-04-18 17:47:12 -0300529 dvb_pll_attach(fc->fe, 0x61, &fc->i2c_adap, &dvb_pll_samsung_tbmv);
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700530 info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address);
531 } else
Michael Krufkyc0b11b92005-11-08 21:35:32 -0800532 /* try the air atsc 3nd generation (lgdt3303) */
533 if ((fc->fe = lgdt330x_attach(&air2pc_atsc_hd5000_config, &fc->i2c_adap)) != NULL) {
534 fc->dev_type = FC_AIR_ATSC3;
Andrew de Quincey56e03142006-04-18 17:47:12 -0300535 fc->fe->ops->tuner_ops.set_params = lgdt3303_tuner_set_params;
Michael Krufkyc0b11b92005-11-08 21:35:32 -0800536 info("found the lgdt3303 at i2c address: 0x%02x",air2pc_atsc_hd5000_config.demod_address);
537 } else
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700538 /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */
539 if ((fc->fe = bcm3510_attach(&air2pc_atsc_first_gen_config, &fc->i2c_adap)) != NULL) {
540 fc->dev_type = FC_AIR_ATSC1;
541 info("found the bcm3510 at i2c address: 0x%02x",air2pc_atsc_first_gen_config.demod_address);
542 } else
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700543 /* try the cable dvb (stv0297) */
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700544 if ((fc->fe = stv0297_attach(&alps_tdee4_stv0297_config, &fc->i2c_adap)) != NULL) {
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700545 fc->dev_type = FC_CABLE;
Andrew de Quincey56e03142006-04-18 17:47:12 -0300546 fc->fe->ops->tuner_ops.set_params = alps_tdee4_stv0297_tuner_set_params;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700547 info("found the stv0297 at i2c address: 0x%02x",alps_tdee4_stv0297_config.demod_address);
548 } else
549 /* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */
Adrian Bunk805e6602006-02-27 00:07:49 -0300550 if ((fc->fe = vp310_mt312_attach(&skystar23_samsung_tbdu18132_config, &fc->i2c_adap)) != NULL) {
Jesper Juhl6a5bdd32006-01-09 15:25:23 -0200551 ops = fc->fe->ops;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700552
Andrew de Quincey56e03142006-04-18 17:47:12 -0300553 ops->tuner_ops.set_params = skystar23_samsung_tbdu18132_tuner_set_params;
554
Jesper Juhl6a5bdd32006-01-09 15:25:23 -0200555 ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
556 ops->diseqc_send_burst = flexcop_diseqc_send_burst;
557 ops->set_tone = flexcop_set_tone;
558 ops->set_voltage = flexcop_set_voltage;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700559
Jesper Juhl6a5bdd32006-01-09 15:25:23 -0200560 fc->fe_sleep = ops->sleep;
561 ops->sleep = flexcop_sleep;
562
563 fc->dev_type = FC_SKY_OLD;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700564 info("found the vp310 (aka mt312) at i2c address: 0x%02x",skystar23_samsung_tbdu18132_config.demod_address);
565 }
566
567 if (fc->fe == NULL) {
568 err("no frontend driver found for this B2C2/FlexCop adapter");
569 return -ENODEV;
570 } else {
571 if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) {
572 err("frontend registration failed!");
Jesper Juhl6a5bdd32006-01-09 15:25:23 -0200573 ops = fc->fe->ops;
574 if (ops->release != NULL)
575 ops->release(fc->fe);
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700576 fc->fe = NULL;
577 return -EINVAL;
578 }
579 }
580 fc->init_state |= FC_STATE_FE_INIT;
581 return 0;
582}
583
584void flexcop_frontend_exit(struct flexcop_device *fc)
585{
586 if (fc->init_state & FC_STATE_FE_INIT)
587 dvb_unregister_frontend(fc->fe);
588
589 fc->init_state &= ~FC_STATE_FE_INIT;
590}