blob: 441ffdf0d9c9f330a89cbfd5b8475a0c6ab65658 [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 */
Michael Krufky827855d2008-04-22 14:46:16 -03008#include <media/tuner.h>
9
Johannes Stezenbach2add87a2005-05-16 21:54:10 -070010#include "flexcop.h"
11
12#include "stv0299.h"
13#include "mt352.h"
Michael Krufky46365f32006-01-23 09:52:39 -020014#include "nxt200x.h"
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -070015#include "bcm3510.h"
Johannes Stezenbach2add87a2005-05-16 21:54:10 -070016#include "stv0297.h"
17#include "mt312.h"
Michael Krufkyc0b11b92005-11-08 21:35:32 -080018#include "lgdt330x.h"
19#include "dvb-pll.h"
Michael Krufky827855d2008-04-22 14:46:16 -030020#include "tuner-simple.h"
Johannes Stezenbach2add87a2005-05-16 21:54:10 -070021
22/* lnb control */
23
24static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
25{
26 struct flexcop_device *fc = fe->dvb->priv;
27 flexcop_ibi_value v;
28 deb_tuner("polarity/voltage = %u\n", voltage);
29
30 v = fc->read_ibi_reg(fc, misc_204);
31 switch (voltage) {
32 case SEC_VOLTAGE_OFF:
33 v.misc_204.ACPI1_sig = 1;
34 break;
35 case SEC_VOLTAGE_13:
36 v.misc_204.ACPI1_sig = 0;
37 v.misc_204.LNB_L_H_sig = 0;
38 break;
39 case SEC_VOLTAGE_18:
40 v.misc_204.ACPI1_sig = 0;
41 v.misc_204.LNB_L_H_sig = 1;
42 break;
43 default:
44 err("unknown SEC_VOLTAGE value");
45 return -EINVAL;
46 }
47 return fc->write_ibi_reg(fc, misc_204, v);
48}
49
50static int flexcop_sleep(struct dvb_frontend* fe)
51{
52 struct flexcop_device *fc = fe->dvb->priv;
53/* flexcop_ibi_value v = fc->read_ibi_reg(fc,misc_204); */
54
55 if (fc->fe_sleep)
56 return fc->fe_sleep(fe);
57
58/* v.misc_204.ACPI3_sig = 1;
59 fc->write_ibi_reg(fc,misc_204,v);*/
60
61 return 0;
62}
63
64static int flexcop_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
65{
66 /* u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc }; */
67 struct flexcop_device *fc = fe->dvb->priv;
68 flexcop_ibi_value v;
69 u16 ax;
70 v.raw = 0;
71
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
Johannes Stezenbach958706c2005-05-16 21:54:19 -070088 v.lnb_switch_freq_200.LNB_CTLHighCount_sig = ax;
89 v.lnb_switch_freq_200.LNB_CTLLowCount_sig = ax == 0 ? 0x1ff : ax;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -070090
91 return fc->write_ibi_reg(fc,lnb_switch_freq_200,v);
92}
93
94static void flexcop_diseqc_send_bit(struct dvb_frontend* fe, int data)
95{
96 flexcop_set_tone(fe, SEC_TONE_ON);
97 udelay(data ? 500 : 1000);
98 flexcop_set_tone(fe, SEC_TONE_OFF);
99 udelay(data ? 1000 : 500);
100}
101
102static void flexcop_diseqc_send_byte(struct dvb_frontend* fe, int data)
103{
104 int i, par = 1, d;
105
106 for (i = 7; i >= 0; i--) {
107 d = (data >> i) & 1;
108 par ^= d;
109 flexcop_diseqc_send_bit(fe, d);
110 }
111
112 flexcop_diseqc_send_bit(fe, par);
113}
114
115static int flexcop_send_diseqc_msg(struct dvb_frontend* fe, int len, u8 *msg, unsigned long burst)
116{
117 int i;
118
119 flexcop_set_tone(fe, SEC_TONE_OFF);
120 mdelay(16);
121
122 for (i = 0; i < len; i++)
123 flexcop_diseqc_send_byte(fe,msg[i]);
124
125 mdelay(16);
126
127 if (burst != -1) {
128 if (burst)
129 flexcop_diseqc_send_byte(fe, 0xff);
130 else {
131 flexcop_set_tone(fe, SEC_TONE_ON);
132 udelay(12500);
133 flexcop_set_tone(fe, SEC_TONE_OFF);
134 }
135 msleep(20);
136 }
137 return 0;
138}
139
140static int flexcop_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
141{
142 return flexcop_send_diseqc_msg(fe, cmd->msg_len, cmd->msg, 0);
143}
144
145static int flexcop_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
146{
147 return flexcop_send_diseqc_msg(fe, 0, NULL, minicmd);
148}
149
150/* dvb-s stv0299 */
151static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
152{
153 u8 aclk = 0;
154 u8 bclk = 0;
155
156 if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
157 else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
158 else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
159 else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
160 else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
161 else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
162
163 stv0299_writereg (fe, 0x13, aclk);
164 stv0299_writereg (fe, 0x14, bclk);
165 stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff);
166 stv0299_writereg (fe, 0x20, (ratio >> 8) & 0xff);
167 stv0299_writereg (fe, 0x21, (ratio ) & 0xf0);
168
169 return 0;
170}
171
Andrew de Quincey56e03142006-04-18 17:47:12 -0300172static int samsung_tbmu24112_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params)
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700173{
174 u8 buf[4];
175 u32 div;
176 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
Andrew de Quincey56e03142006-04-18 17:47:12 -0300177 struct flexcop_device *fc = fe->dvb->priv;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700178
179 div = params->frequency / 125;
180
181 buf[0] = (div >> 8) & 0x7f;
182 buf[1] = div & 0xff;
183 buf[2] = 0x84; /* 0xC4 */
184 buf[3] = 0x08;
185
186 if (params->frequency < 1500000) buf[3] |= 0x10;
187
Patrick Boettcherdea74862006-05-14 05:01:31 -0300188 if (fe->ops.i2c_gate_ctrl)
189 fe->ops.i2c_gate_ctrl(fe, 1);
Andrew de Quincey56e03142006-04-18 17:47:12 -0300190 if (i2c_transfer(&fc->i2c_adap, &msg, 1) != 1) {
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700191 return -EIO;
Andrew de Quincey56e03142006-04-18 17:47:12 -0300192 }
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700193 return 0;
194}
195
196static u8 samsung_tbmu24112_inittab[] = {
197 0x01, 0x15,
198 0x02, 0x30,
199 0x03, 0x00,
200 0x04, 0x7D,
201 0x05, 0x35,
202 0x06, 0x02,
203 0x07, 0x00,
204 0x08, 0xC3,
205 0x0C, 0x00,
206 0x0D, 0x81,
207 0x0E, 0x23,
208 0x0F, 0x12,
209 0x10, 0x7E,
210 0x11, 0x84,
211 0x12, 0xB9,
212 0x13, 0x88,
213 0x14, 0x89,
214 0x15, 0xC9,
215 0x16, 0x00,
216 0x17, 0x5C,
217 0x18, 0x00,
218 0x19, 0x00,
219 0x1A, 0x00,
220 0x1C, 0x00,
221 0x1D, 0x00,
222 0x1E, 0x00,
223 0x1F, 0x3A,
224 0x20, 0x2E,
225 0x21, 0x80,
226 0x22, 0xFF,
227 0x23, 0xC1,
228 0x28, 0x00,
229 0x29, 0x1E,
230 0x2A, 0x14,
231 0x2B, 0x0F,
232 0x2C, 0x09,
233 0x2D, 0x05,
234 0x31, 0x1F,
235 0x32, 0x19,
236 0x33, 0xFE,
237 0x34, 0x93,
238 0xff, 0xff,
239};
240
241static struct stv0299_config samsung_tbmu24112_config = {
242 .demod_address = 0x68,
243 .inittab = samsung_tbmu24112_inittab,
244 .mclk = 88000000UL,
245 .invert = 0,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700246 .skip_reinit = 0,
247 .lock_output = STV0229_LOCKOUTPUT_LK,
248 .volt13_op0_op1 = STV0299_VOLT13_OP1,
249 .min_delay_ms = 100,
250 .set_symbol_rate = samsung_tbmu24112_set_symbol_rate,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700251};
252
253/* dvb-t mt352 */
254static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
255{
256 static u8 mt352_clock_config [] = { 0x89, 0x18, 0x2d };
257 static u8 mt352_reset [] = { 0x50, 0x80 };
258 static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
259 static u8 mt352_agc_cfg [] = { 0x67, 0x28, 0xa1 };
260 static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
261
262 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
263 udelay(2000);
264 mt352_write(fe, mt352_reset, sizeof(mt352_reset));
265 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
266
267 mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
268 mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
269
270 return 0;
271}
272
Andrew de Quincey56e03142006-04-18 17:47:12 -0300273static 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 -0700274{
275 u32 div;
276 unsigned char bs = 0;
277
Andrew de Quincey56e03142006-04-18 17:47:12 -0300278 if (buf_len < 5)
279 return -EINVAL;
280
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700281 #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
282 div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
283
284 if (params->frequency >= 48000000 && params->frequency <= 154000000) bs = 0x09;
285 if (params->frequency >= 161000000 && params->frequency <= 439000000) bs = 0x0a;
286 if (params->frequency >= 447000000 && params->frequency <= 863000000) bs = 0x08;
287
Andrew de Quincey56e03142006-04-18 17:47:12 -0300288 pllbuf[0] = 0x61;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700289 pllbuf[1] = div >> 8;
290 pllbuf[2] = div & 0xff;
291 pllbuf[3] = 0xcc;
292 pllbuf[4] = bs;
293
Andrew de Quincey56e03142006-04-18 17:47:12 -0300294 return 5;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700295}
296
297static struct mt352_config samsung_tdtc9251dh0_config = {
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700298 .demod_address = 0x0f,
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700299 .demod_init = samsung_tdtc9251dh0_demod_init,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700300};
301
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700302static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700303{
304 struct flexcop_device *fc = fe->dvb->priv;
305 return request_firmware(fw, name, fc->dev);
306}
307
Michael Krufkyc0b11b92005-11-08 21:35:32 -0800308static struct lgdt330x_config air2pc_atsc_hd5000_config = {
309 .demod_address = 0x59,
310 .demod_chip = LGDT3303,
311 .serial_mpeg = 0x04,
Michael Krufkyc0b11b92005-11-08 21:35:32 -0800312 .clock_polarity_flip = 1,
313};
314
Michael Krufky46365f32006-01-23 09:52:39 -0200315static struct nxt200x_config samsung_tbmv_config = {
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700316 .demod_address = 0x0a,
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700317};
318
319static struct bcm3510_config air2pc_atsc_first_gen_config = {
320 .demod_address = 0x0f,
321 .request_firmware = flexcop_fe_request_firmware,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700322};
323
Andrew de Quincey56e03142006-04-18 17:47:12 -0300324static int skystar23_samsung_tbdu18132_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params)
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700325{
326 u8 buf[4];
327 u32 div;
328 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
329 struct flexcop_device *fc = fe->dvb->priv;
330
331 div = (params->frequency + (125/2)) / 125;
332
333 buf[0] = (div >> 8) & 0x7f;
334 buf[1] = (div >> 0) & 0xff;
335 buf[2] = 0x84 | ((div >> 10) & 0x60);
336 buf[3] = 0x80;
337
338 if (params->frequency < 1550000)
339 buf[3] |= 0x02;
340
Patrick Boettcherdea74862006-05-14 05:01:31 -0300341 if (fe->ops.i2c_gate_ctrl)
342 fe->ops.i2c_gate_ctrl(fe, 1);
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700343 if (i2c_transfer(&fc->i2c_adap, &msg, 1) != 1)
344 return -EIO;
345 return 0;
346}
347
348static struct mt312_config skystar23_samsung_tbdu18132_config = {
349
350 .demod_address = 0x0e,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700351};
352
Adrian Bunkdd00b1e2006-05-29 12:31:44 -0300353static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe,
354 struct dvb_frontend_parameters *fep)
Andrew de Quincey56e03142006-04-18 17:47:12 -0300355{
356 struct flexcop_device *fc = fe->dvb->priv;
357 u8 buf[4];
358 u16 div;
359 int ret;
360
361/* 62.5 kHz * 10 */
362#define REF_FREQ 625
363#define FREQ_OFFSET 36125
364
365 div = ((fep->frequency/1000 + FREQ_OFFSET ) * 10) / REF_FREQ; // 4 MHz = 4000 KHz
366
367 buf[0] = (u8)( div >> 8) & 0x7f;
368 buf[1] = (u8) div & 0xff;
369
370/* F(osc) = N * Reference Freq. (62.5 kHz)
371 * byte 2 : 0 N14 N13 N12 N11 N10 N9 N8
372 * byte 3 : N7 N6 N5 N4 N3 N2 N1 N0
373 * byte 4 : 1 * * AGD R3 R2 R1 R0
374 * byte 5 : C1 * RE RTS BS4 BS3 BS2 BS1
375 * AGD = 1, R3 R2 R1 R0 = 0 1 0 1 => byte 4 = 1**10101 = 0x95 */
376 buf[2] = 0x95;
377
378// Range(MHz) C1 * RE RTS BS4 BS3 BS2 BS1 Byte 5
379// 47 - 153 0 * 0 0 0 0 0 1 0x01
380// 153 - 430 0 * 0 0 0 0 1 0 0x02
381// 430 - 822 0 * 0 0 1 0 0 0 0x08
382// 822 - 862 1 * 0 0 1 0 0 0 0x88
383
384 if (fep->frequency <= 153000000) buf[3] = 0x01;
385 else if (fep->frequency <= 430000000) buf[3] = 0x02;
386 else if (fep->frequency <= 822000000) buf[3] = 0x08;
387 else buf[3] = 0x88;
388
Patrick Boettcherdea74862006-05-14 05:01:31 -0300389 if (fe->ops.i2c_gate_ctrl)
Antti Seppälä9d85d772006-12-20 11:10:35 -0300390 fe->ops.i2c_gate_ctrl(fe, 0);
Andrew de Quincey56e03142006-04-18 17:47:12 -0300391 deb_tuner("tuner buffer for %d Hz: %x %x %x %x\n",fep->frequency, buf[0],buf[1],buf[2],buf[3]);
Antti Seppälä9d85d772006-12-20 11:10:35 -0300392 ret = fc->i2c_request(fc, FC_WRITE, FC_I2C_PORT_TUNER, 0x61, buf[0], &buf[1], 3);
Andrew de Quincey56e03142006-04-18 17:47:12 -0300393 deb_tuner("tuner write returned: %d\n",ret);
394
395 return 0;
396}
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700397
398static u8 alps_tdee4_stv0297_inittab[] = {
399 0x80, 0x01,
400 0x80, 0x00,
401 0x81, 0x01,
402 0x81, 0x00,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300403 0x00, 0x48,
404 0x01, 0x58,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700405 0x03, 0x00,
406 0x04, 0x00,
407 0x07, 0x00,
408 0x08, 0x00,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700409 0x30, 0xff,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300410 0x31, 0x9d,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700411 0x32, 0xff,
412 0x33, 0x00,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300413 0x34, 0x29,
414 0x35, 0x55,
415 0x36, 0x80,
416 0x37, 0x6e,
417 0x38, 0x9c,
418 0x40, 0x1a,
419 0x41, 0xfe,
420 0x42, 0x33,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700421 0x43, 0x00,
422 0x44, 0xff,
423 0x45, 0x00,
424 0x46, 0x00,
425 0x49, 0x04,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300426 0x4a, 0x51,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700427 0x4b, 0xf8,
428 0x52, 0x30,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300429 0x53, 0x06,
430 0x59, 0x06,
431 0x5a, 0x5e,
432 0x5b, 0x04,
433 0x61, 0x49,
434 0x62, 0x0a,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700435 0x70, 0xff,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300436 0x71, 0x04,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700437 0x72, 0x00,
438 0x73, 0x00,
439 0x74, 0x0c,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300440 0x80, 0x20,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700441 0x81, 0x00,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300442 0x82, 0x30,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700443 0x83, 0x00,
444 0x84, 0x04,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300445 0x85, 0x22,
446 0x86, 0x08,
447 0x87, 0x1b,
448 0x88, 0x00,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700449 0x89, 0x00,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300450 0x90, 0x00,
451 0x91, 0x04,
452 0xa0, 0x86,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700453 0xa1, 0x00,
454 0xa2, 0x00,
455 0xb0, 0x91,
456 0xb1, 0x0b,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300457 0xc0, 0x5b,
458 0xc1, 0x10,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700459 0xc2, 0x12,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300460 0xd0, 0x02,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700461 0xd1, 0x00,
462 0xd2, 0x00,
463 0xd3, 0x00,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300464 0xd4, 0x02,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700465 0xd5, 0x00,
466 0xde, 0x00,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300467 0xdf, 0x01,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700468 0xff, 0xff,
469};
470
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700471static struct stv0297_config alps_tdee4_stv0297_config = {
472 .demod_address = 0x1c,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700473 .inittab = alps_tdee4_stv0297_inittab,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700474// .invert = 1,
475// .pll_set = alps_tdee4_stv0297_pll_set,
476};
477
478/* try to figure out the frontend, each card/box can have on of the following list */
479int flexcop_frontend_init(struct flexcop_device *fc)
480{
Jesper Juhl6a5bdd32006-01-09 15:25:23 -0200481 struct dvb_frontend_ops *ops;
482
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700483 /* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */
Andrew de Quincey2bfe0312006-08-08 09:10:08 -0300484 if ((fc->fe = dvb_attach(stv0299_attach, &samsung_tbmu24112_config, &fc->i2c_adap)) != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -0300485 ops = &fc->fe->ops;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700486
Andrew de Quincey56e03142006-04-18 17:47:12 -0300487 ops->tuner_ops.set_params = samsung_tbmu24112_tuner_set_params;
488
Jesper Juhl6a5bdd32006-01-09 15:25:23 -0200489 ops->set_voltage = flexcop_set_voltage;
490
491 fc->fe_sleep = ops->sleep;
492 ops->sleep = flexcop_sleep;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700493
494 fc->dev_type = FC_SKY;
495 info("found the stv0299 at i2c address: 0x%02x",samsung_tbmu24112_config.demod_address);
496 } else
497 /* try the air dvb-t (mt352/Samsung tdtc9251dh0(??)) */
Andrew de Quincey2bfe0312006-08-08 09:10:08 -0300498 if ((fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, &fc->i2c_adap)) != NULL ) {
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700499 fc->dev_type = FC_AIR_DVB;
Patrick Boettcherdea74862006-05-14 05:01:31 -0300500 fc->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700501 info("found the mt352 at i2c address: 0x%02x",samsung_tdtc9251dh0_config.demod_address);
502 } else
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700503 /* try the air atsc 2nd generation (nxt2002) */
Andrew de Quincey2bfe0312006-08-08 09:10:08 -0300504 if ((fc->fe = dvb_attach(nxt200x_attach, &samsung_tbmv_config, &fc->i2c_adap)) != NULL) {
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700505 fc->dev_type = FC_AIR_ATSC2;
Michael Krufky47a99912007-06-12 16:10:51 -0300506 dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL, DVB_PLL_SAMSUNG_TBMV);
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700507 info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address);
508 } else
Michael Krufkyc0b11b92005-11-08 21:35:32 -0800509 /* try the air atsc 3nd generation (lgdt3303) */
Andrew de Quincey2bfe0312006-08-08 09:10:08 -0300510 if ((fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, &fc->i2c_adap)) != NULL) {
Michael Krufkyc0b11b92005-11-08 21:35:32 -0800511 fc->dev_type = FC_AIR_ATSC3;
Michael Krufky827855d2008-04-22 14:46:16 -0300512 dvb_attach(simple_tuner_attach, fc->fe,
513 &fc->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF);
Michael Krufkyc0b11b92005-11-08 21:35:32 -0800514 info("found the lgdt3303 at i2c address: 0x%02x",air2pc_atsc_hd5000_config.demod_address);
515 } else
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700516 /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */
Andrew de Quincey2bfe0312006-08-08 09:10:08 -0300517 if ((fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, &fc->i2c_adap)) != NULL) {
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700518 fc->dev_type = FC_AIR_ATSC1;
519 info("found the bcm3510 at i2c address: 0x%02x",air2pc_atsc_first_gen_config.demod_address);
520 } else
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700521 /* try the cable dvb (stv0297) */
Andrew de Quincey2bfe0312006-08-08 09:10:08 -0300522 if ((fc->fe = dvb_attach(stv0297_attach, &alps_tdee4_stv0297_config, &fc->i2c_adap)) != NULL) {
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700523 fc->dev_type = FC_CABLE;
Patrick Boettcherdea74862006-05-14 05:01:31 -0300524 fc->fe->ops.tuner_ops.set_params = alps_tdee4_stv0297_tuner_set_params;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700525 info("found the stv0297 at i2c address: 0x%02x",alps_tdee4_stv0297_config.demod_address);
526 } else
527 /* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */
Andrew de Quincey2bfe0312006-08-08 09:10:08 -0300528 if ((fc->fe = dvb_attach(vp310_mt312_attach, &skystar23_samsung_tbdu18132_config, &fc->i2c_adap)) != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -0300529 ops = &fc->fe->ops;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700530
Andrew de Quincey56e03142006-04-18 17:47:12 -0300531 ops->tuner_ops.set_params = skystar23_samsung_tbdu18132_tuner_set_params;
532
Jesper Juhl6a5bdd32006-01-09 15:25:23 -0200533 ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
534 ops->diseqc_send_burst = flexcop_diseqc_send_burst;
535 ops->set_tone = flexcop_set_tone;
536 ops->set_voltage = flexcop_set_voltage;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700537
Jesper Juhl6a5bdd32006-01-09 15:25:23 -0200538 fc->fe_sleep = ops->sleep;
539 ops->sleep = flexcop_sleep;
540
541 fc->dev_type = FC_SKY_OLD;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700542 info("found the vp310 (aka mt312) at i2c address: 0x%02x",skystar23_samsung_tbdu18132_config.demod_address);
543 }
544
545 if (fc->fe == NULL) {
546 err("no frontend driver found for this B2C2/FlexCop adapter");
547 return -ENODEV;
548 } else {
549 if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) {
550 err("frontend registration failed!");
Andrew de Quinceyf52a8382006-08-08 09:10:09 -0300551 dvb_frontend_detach(fc->fe);
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700552 fc->fe = NULL;
553 return -EINVAL;
554 }
555 }
556 fc->init_state |= FC_STATE_FE_INIT;
557 return 0;
558}
559
560void flexcop_frontend_exit(struct flexcop_device *fc)
561{
Andrew de Quincey2bfe0312006-08-08 09:10:08 -0300562 if (fc->init_state & FC_STATE_FE_INIT) {
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700563 dvb_unregister_frontend(fc->fe);
Andrew de Quinceyf52a8382006-08-08 09:10:09 -0300564 dvb_frontend_detach(fc->fe);
Andrew de Quincey2bfe0312006-08-08 09:10:08 -0300565 }
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700566
567 fc->init_state &= ~FC_STATE_FE_INIT;
568}