blob: 0378fd64659141ec73933149637552d71aacc0f8 [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"
17#include "dvb-pll.h"
Johannes Stezenbach2add87a2005-05-16 21:54:10 -070018
19/* lnb control */
20
21static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
22{
23 struct flexcop_device *fc = fe->dvb->priv;
24 flexcop_ibi_value v;
25 deb_tuner("polarity/voltage = %u\n", voltage);
26
27 v = fc->read_ibi_reg(fc, misc_204);
28 switch (voltage) {
29 case SEC_VOLTAGE_OFF:
30 v.misc_204.ACPI1_sig = 1;
31 break;
32 case SEC_VOLTAGE_13:
33 v.misc_204.ACPI1_sig = 0;
34 v.misc_204.LNB_L_H_sig = 0;
35 break;
36 case SEC_VOLTAGE_18:
37 v.misc_204.ACPI1_sig = 0;
38 v.misc_204.LNB_L_H_sig = 1;
39 break;
40 default:
41 err("unknown SEC_VOLTAGE value");
42 return -EINVAL;
43 }
44 return fc->write_ibi_reg(fc, misc_204, v);
45}
46
47static int flexcop_sleep(struct dvb_frontend* fe)
48{
49 struct flexcop_device *fc = fe->dvb->priv;
50/* flexcop_ibi_value v = fc->read_ibi_reg(fc,misc_204); */
51
52 if (fc->fe_sleep)
53 return fc->fe_sleep(fe);
54
55/* v.misc_204.ACPI3_sig = 1;
56 fc->write_ibi_reg(fc,misc_204,v);*/
57
58 return 0;
59}
60
61static int flexcop_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
62{
63 /* u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc }; */
64 struct flexcop_device *fc = fe->dvb->priv;
65 flexcop_ibi_value v;
66 u16 ax;
67 v.raw = 0;
68
69 deb_tuner("tone = %u\n",tone);
70
71 switch (tone) {
72 case SEC_TONE_ON:
73 ax = 0x01ff;
74 break;
75 case SEC_TONE_OFF:
76 ax = 0;
77 break;
78 default:
79 err("unknown SEC_TONE value");
80 return -EINVAL;
81 }
82
83 v.lnb_switch_freq_200.LNB_CTLPrescaler_sig = 1; /* divide by 2 */
84
Johannes Stezenbach958706c2005-05-16 21:54:19 -070085 v.lnb_switch_freq_200.LNB_CTLHighCount_sig = ax;
86 v.lnb_switch_freq_200.LNB_CTLLowCount_sig = ax == 0 ? 0x1ff : ax;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -070087
88 return fc->write_ibi_reg(fc,lnb_switch_freq_200,v);
89}
90
91static void flexcop_diseqc_send_bit(struct dvb_frontend* fe, int data)
92{
93 flexcop_set_tone(fe, SEC_TONE_ON);
94 udelay(data ? 500 : 1000);
95 flexcop_set_tone(fe, SEC_TONE_OFF);
96 udelay(data ? 1000 : 500);
97}
98
99static void flexcop_diseqc_send_byte(struct dvb_frontend* fe, int data)
100{
101 int i, par = 1, d;
102
103 for (i = 7; i >= 0; i--) {
104 d = (data >> i) & 1;
105 par ^= d;
106 flexcop_diseqc_send_bit(fe, d);
107 }
108
109 flexcop_diseqc_send_bit(fe, par);
110}
111
112static int flexcop_send_diseqc_msg(struct dvb_frontend* fe, 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
122 mdelay(16);
123
124 if (burst != -1) {
125 if (burst)
126 flexcop_diseqc_send_byte(fe, 0xff);
127 else {
128 flexcop_set_tone(fe, SEC_TONE_ON);
129 udelay(12500);
130 flexcop_set_tone(fe, SEC_TONE_OFF);
131 }
132 msleep(20);
133 }
134 return 0;
135}
136
137static int flexcop_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
138{
139 return flexcop_send_diseqc_msg(fe, cmd->msg_len, cmd->msg, 0);
140}
141
142static int flexcop_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
143{
144 return flexcop_send_diseqc_msg(fe, 0, NULL, minicmd);
145}
146
147/* dvb-s stv0299 */
148static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
149{
150 u8 aclk = 0;
151 u8 bclk = 0;
152
153 if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
154 else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
155 else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
156 else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
157 else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
158 else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
159
160 stv0299_writereg (fe, 0x13, aclk);
161 stv0299_writereg (fe, 0x14, bclk);
162 stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff);
163 stv0299_writereg (fe, 0x20, (ratio >> 8) & 0xff);
164 stv0299_writereg (fe, 0x21, (ratio ) & 0xf0);
165
166 return 0;
167}
168
Andrew de Quincey56e03142006-04-18 17:47:12 -0300169static int samsung_tbmu24112_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params)
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700170{
171 u8 buf[4];
172 u32 div;
173 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
Andrew de Quincey56e03142006-04-18 17:47:12 -0300174 struct flexcop_device *fc = fe->dvb->priv;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700175
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
Patrick Boettcherdea74862006-05-14 05:01:31 -0300185 if (fe->ops.i2c_gate_ctrl)
186 fe->ops.i2c_gate_ctrl(fe, 1);
Andrew de Quincey56e03142006-04-18 17:47:12 -0300187 if (i2c_transfer(&fc->i2c_adap, &msg, 1) != 1) {
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700188 return -EIO;
Andrew de Quincey56e03142006-04-18 17:47:12 -0300189 }
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700190 return 0;
191}
192
193static u8 samsung_tbmu24112_inittab[] = {
194 0x01, 0x15,
195 0x02, 0x30,
196 0x03, 0x00,
197 0x04, 0x7D,
198 0x05, 0x35,
199 0x06, 0x02,
200 0x07, 0x00,
201 0x08, 0xC3,
202 0x0C, 0x00,
203 0x0D, 0x81,
204 0x0E, 0x23,
205 0x0F, 0x12,
206 0x10, 0x7E,
207 0x11, 0x84,
208 0x12, 0xB9,
209 0x13, 0x88,
210 0x14, 0x89,
211 0x15, 0xC9,
212 0x16, 0x00,
213 0x17, 0x5C,
214 0x18, 0x00,
215 0x19, 0x00,
216 0x1A, 0x00,
217 0x1C, 0x00,
218 0x1D, 0x00,
219 0x1E, 0x00,
220 0x1F, 0x3A,
221 0x20, 0x2E,
222 0x21, 0x80,
223 0x22, 0xFF,
224 0x23, 0xC1,
225 0x28, 0x00,
226 0x29, 0x1E,
227 0x2A, 0x14,
228 0x2B, 0x0F,
229 0x2C, 0x09,
230 0x2D, 0x05,
231 0x31, 0x1F,
232 0x32, 0x19,
233 0x33, 0xFE,
234 0x34, 0x93,
235 0xff, 0xff,
236};
237
238static struct stv0299_config samsung_tbmu24112_config = {
239 .demod_address = 0x68,
240 .inittab = samsung_tbmu24112_inittab,
241 .mclk = 88000000UL,
242 .invert = 0,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700243 .skip_reinit = 0,
244 .lock_output = STV0229_LOCKOUTPUT_LK,
245 .volt13_op0_op1 = STV0299_VOLT13_OP1,
246 .min_delay_ms = 100,
247 .set_symbol_rate = samsung_tbmu24112_set_symbol_rate,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700248};
249
250/* dvb-t mt352 */
251static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
252{
253 static u8 mt352_clock_config [] = { 0x89, 0x18, 0x2d };
254 static u8 mt352_reset [] = { 0x50, 0x80 };
255 static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
256 static u8 mt352_agc_cfg [] = { 0x67, 0x28, 0xa1 };
257 static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
258
259 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
260 udelay(2000);
261 mt352_write(fe, mt352_reset, sizeof(mt352_reset));
262 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
263
264 mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
265 mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
266
267 return 0;
268}
269
Andrew de Quincey56e03142006-04-18 17:47:12 -0300270static 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 -0700271{
272 u32 div;
273 unsigned char bs = 0;
274
Andrew de Quincey56e03142006-04-18 17:47:12 -0300275 if (buf_len < 5)
276 return -EINVAL;
277
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700278 #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
279 div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
280
281 if (params->frequency >= 48000000 && params->frequency <= 154000000) bs = 0x09;
282 if (params->frequency >= 161000000 && params->frequency <= 439000000) bs = 0x0a;
283 if (params->frequency >= 447000000 && params->frequency <= 863000000) bs = 0x08;
284
Andrew de Quincey56e03142006-04-18 17:47:12 -0300285 pllbuf[0] = 0x61;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700286 pllbuf[1] = div >> 8;
287 pllbuf[2] = div & 0xff;
288 pllbuf[3] = 0xcc;
289 pllbuf[4] = bs;
290
Andrew de Quincey56e03142006-04-18 17:47:12 -0300291 return 5;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700292}
293
294static struct mt352_config samsung_tdtc9251dh0_config = {
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700295 .demod_address = 0x0f,
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700296 .demod_init = samsung_tdtc9251dh0_demod_init,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700297};
298
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700299static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700300{
301 struct flexcop_device *fc = fe->dvb->priv;
302 return request_firmware(fw, name, fc->dev);
303}
304
Michael Krufkyc0b11b92005-11-08 21:35:32 -0800305static struct lgdt330x_config air2pc_atsc_hd5000_config = {
306 .demod_address = 0x59,
307 .demod_chip = LGDT3303,
308 .serial_mpeg = 0x04,
Michael Krufkyc0b11b92005-11-08 21:35:32 -0800309 .clock_polarity_flip = 1,
310};
311
Michael Krufky46365f32006-01-23 09:52:39 -0200312static struct nxt200x_config samsung_tbmv_config = {
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700313 .demod_address = 0x0a,
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700314};
315
316static struct bcm3510_config air2pc_atsc_first_gen_config = {
317 .demod_address = 0x0f,
318 .request_firmware = flexcop_fe_request_firmware,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700319};
320
Andrew de Quincey56e03142006-04-18 17:47:12 -0300321static int skystar23_samsung_tbdu18132_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params)
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700322{
323 u8 buf[4];
324 u32 div;
325 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
326 struct flexcop_device *fc = fe->dvb->priv;
327
328 div = (params->frequency + (125/2)) / 125;
329
330 buf[0] = (div >> 8) & 0x7f;
331 buf[1] = (div >> 0) & 0xff;
332 buf[2] = 0x84 | ((div >> 10) & 0x60);
333 buf[3] = 0x80;
334
335 if (params->frequency < 1550000)
336 buf[3] |= 0x02;
337
Patrick Boettcherdea74862006-05-14 05:01:31 -0300338 if (fe->ops.i2c_gate_ctrl)
339 fe->ops.i2c_gate_ctrl(fe, 1);
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700340 if (i2c_transfer(&fc->i2c_adap, &msg, 1) != 1)
341 return -EIO;
342 return 0;
343}
344
345static struct mt312_config skystar23_samsung_tbdu18132_config = {
346
347 .demod_address = 0x0e,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700348};
349
Adrian Bunkdd00b1e2006-05-29 12:31:44 -0300350static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe,
351 struct dvb_frontend_parameters *fep)
Andrew de Quincey56e03142006-04-18 17:47:12 -0300352{
353 struct flexcop_device *fc = fe->dvb->priv;
354 u8 buf[4];
355 u16 div;
356 int ret;
357
358/* 62.5 kHz * 10 */
359#define REF_FREQ 625
360#define FREQ_OFFSET 36125
361
362 div = ((fep->frequency/1000 + FREQ_OFFSET ) * 10) / REF_FREQ; // 4 MHz = 4000 KHz
363
364 buf[0] = (u8)( div >> 8) & 0x7f;
365 buf[1] = (u8) div & 0xff;
366
367/* F(osc) = N * Reference Freq. (62.5 kHz)
368 * byte 2 : 0 N14 N13 N12 N11 N10 N9 N8
369 * byte 3 : N7 N6 N5 N4 N3 N2 N1 N0
370 * byte 4 : 1 * * AGD R3 R2 R1 R0
371 * byte 5 : C1 * RE RTS BS4 BS3 BS2 BS1
372 * AGD = 1, R3 R2 R1 R0 = 0 1 0 1 => byte 4 = 1**10101 = 0x95 */
373 buf[2] = 0x95;
374
375// Range(MHz) C1 * RE RTS BS4 BS3 BS2 BS1 Byte 5
376// 47 - 153 0 * 0 0 0 0 0 1 0x01
377// 153 - 430 0 * 0 0 0 0 1 0 0x02
378// 430 - 822 0 * 0 0 1 0 0 0 0x08
379// 822 - 862 1 * 0 0 1 0 0 0 0x88
380
381 if (fep->frequency <= 153000000) buf[3] = 0x01;
382 else if (fep->frequency <= 430000000) buf[3] = 0x02;
383 else if (fep->frequency <= 822000000) buf[3] = 0x08;
384 else buf[3] = 0x88;
385
Patrick Boettcherdea74862006-05-14 05:01:31 -0300386 if (fe->ops.i2c_gate_ctrl)
Antti Seppälä9d85d772006-12-20 11:10:35 -0300387 fe->ops.i2c_gate_ctrl(fe, 0);
Andrew de Quincey56e03142006-04-18 17:47:12 -0300388 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 -0300389 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 -0300390 deb_tuner("tuner write returned: %d\n",ret);
391
392 return 0;
393}
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700394
395static u8 alps_tdee4_stv0297_inittab[] = {
396 0x80, 0x01,
397 0x80, 0x00,
398 0x81, 0x01,
399 0x81, 0x00,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300400 0x00, 0x48,
401 0x01, 0x58,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700402 0x03, 0x00,
403 0x04, 0x00,
404 0x07, 0x00,
405 0x08, 0x00,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700406 0x30, 0xff,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300407 0x31, 0x9d,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700408 0x32, 0xff,
409 0x33, 0x00,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300410 0x34, 0x29,
411 0x35, 0x55,
412 0x36, 0x80,
413 0x37, 0x6e,
414 0x38, 0x9c,
415 0x40, 0x1a,
416 0x41, 0xfe,
417 0x42, 0x33,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700418 0x43, 0x00,
419 0x44, 0xff,
420 0x45, 0x00,
421 0x46, 0x00,
422 0x49, 0x04,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300423 0x4a, 0x51,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700424 0x4b, 0xf8,
425 0x52, 0x30,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300426 0x53, 0x06,
427 0x59, 0x06,
428 0x5a, 0x5e,
429 0x5b, 0x04,
430 0x61, 0x49,
431 0x62, 0x0a,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700432 0x70, 0xff,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300433 0x71, 0x04,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700434 0x72, 0x00,
435 0x73, 0x00,
436 0x74, 0x0c,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300437 0x80, 0x20,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700438 0x81, 0x00,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300439 0x82, 0x30,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700440 0x83, 0x00,
441 0x84, 0x04,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300442 0x85, 0x22,
443 0x86, 0x08,
444 0x87, 0x1b,
445 0x88, 0x00,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700446 0x89, 0x00,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300447 0x90, 0x00,
448 0x91, 0x04,
449 0xa0, 0x86,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700450 0xa1, 0x00,
451 0xa2, 0x00,
452 0xb0, 0x91,
453 0xb1, 0x0b,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300454 0xc0, 0x5b,
455 0xc1, 0x10,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700456 0xc2, 0x12,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300457 0xd0, 0x02,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700458 0xd1, 0x00,
459 0xd2, 0x00,
460 0xd3, 0x00,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300461 0xd4, 0x02,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700462 0xd5, 0x00,
463 0xde, 0x00,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300464 0xdf, 0x01,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700465 0xff, 0xff,
466};
467
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700468static struct stv0297_config alps_tdee4_stv0297_config = {
469 .demod_address = 0x1c,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700470 .inittab = alps_tdee4_stv0297_inittab,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700471// .invert = 1,
472// .pll_set = alps_tdee4_stv0297_pll_set,
473};
474
475/* try to figure out the frontend, each card/box can have on of the following list */
476int flexcop_frontend_init(struct flexcop_device *fc)
477{
Jesper Juhl6a5bdd32006-01-09 15:25:23 -0200478 struct dvb_frontend_ops *ops;
479
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700480 /* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */
Andrew de Quincey2bfe0312006-08-08 09:10:08 -0300481 if ((fc->fe = dvb_attach(stv0299_attach, &samsung_tbmu24112_config, &fc->i2c_adap)) != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -0300482 ops = &fc->fe->ops;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700483
Andrew de Quincey56e03142006-04-18 17:47:12 -0300484 ops->tuner_ops.set_params = samsung_tbmu24112_tuner_set_params;
485
Jesper Juhl6a5bdd32006-01-09 15:25:23 -0200486 ops->set_voltage = flexcop_set_voltage;
487
488 fc->fe_sleep = ops->sleep;
489 ops->sleep = flexcop_sleep;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700490
491 fc->dev_type = FC_SKY;
492 info("found the stv0299 at i2c address: 0x%02x",samsung_tbmu24112_config.demod_address);
493 } else
494 /* try the air dvb-t (mt352/Samsung tdtc9251dh0(??)) */
Andrew de Quincey2bfe0312006-08-08 09:10:08 -0300495 if ((fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, &fc->i2c_adap)) != NULL ) {
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700496 fc->dev_type = FC_AIR_DVB;
Patrick Boettcherdea74862006-05-14 05:01:31 -0300497 fc->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700498 info("found the mt352 at i2c address: 0x%02x",samsung_tdtc9251dh0_config.demod_address);
499 } else
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700500 /* try the air atsc 2nd generation (nxt2002) */
Andrew de Quincey2bfe0312006-08-08 09:10:08 -0300501 if ((fc->fe = dvb_attach(nxt200x_attach, &samsung_tbmv_config, &fc->i2c_adap)) != NULL) {
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700502 fc->dev_type = FC_AIR_ATSC2;
Michael Krufky47a99912007-06-12 16:10:51 -0300503 dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL, DVB_PLL_SAMSUNG_TBMV);
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700504 info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address);
505 } else
Michael Krufkyc0b11b92005-11-08 21:35:32 -0800506 /* try the air atsc 3nd generation (lgdt3303) */
Andrew de Quincey2bfe0312006-08-08 09:10:08 -0300507 if ((fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, &fc->i2c_adap)) != NULL) {
Michael Krufkyc0b11b92005-11-08 21:35:32 -0800508 fc->dev_type = FC_AIR_ATSC3;
Michael Krufky47a99912007-06-12 16:10:51 -0300509 dvb_attach(dvb_pll_attach, fc->fe, 0x61, &fc->i2c_adap, DVB_PLL_LG_TDVS_H06XF);
Michael Krufkyc0b11b92005-11-08 21:35:32 -0800510 info("found the lgdt3303 at i2c address: 0x%02x",air2pc_atsc_hd5000_config.demod_address);
511 } else
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700512 /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */
Andrew de Quincey2bfe0312006-08-08 09:10:08 -0300513 if ((fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, &fc->i2c_adap)) != NULL) {
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700514 fc->dev_type = FC_AIR_ATSC1;
515 info("found the bcm3510 at i2c address: 0x%02x",air2pc_atsc_first_gen_config.demod_address);
516 } else
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700517 /* try the cable dvb (stv0297) */
Andrew de Quincey2bfe0312006-08-08 09:10:08 -0300518 if ((fc->fe = dvb_attach(stv0297_attach, &alps_tdee4_stv0297_config, &fc->i2c_adap)) != NULL) {
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700519 fc->dev_type = FC_CABLE;
Patrick Boettcherdea74862006-05-14 05:01:31 -0300520 fc->fe->ops.tuner_ops.set_params = alps_tdee4_stv0297_tuner_set_params;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700521 info("found the stv0297 at i2c address: 0x%02x",alps_tdee4_stv0297_config.demod_address);
522 } else
523 /* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */
Andrew de Quincey2bfe0312006-08-08 09:10:08 -0300524 if ((fc->fe = dvb_attach(vp310_mt312_attach, &skystar23_samsung_tbdu18132_config, &fc->i2c_adap)) != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -0300525 ops = &fc->fe->ops;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700526
Andrew de Quincey56e03142006-04-18 17:47:12 -0300527 ops->tuner_ops.set_params = skystar23_samsung_tbdu18132_tuner_set_params;
528
Jesper Juhl6a5bdd32006-01-09 15:25:23 -0200529 ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
530 ops->diseqc_send_burst = flexcop_diseqc_send_burst;
531 ops->set_tone = flexcop_set_tone;
532 ops->set_voltage = flexcop_set_voltage;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700533
Jesper Juhl6a5bdd32006-01-09 15:25:23 -0200534 fc->fe_sleep = ops->sleep;
535 ops->sleep = flexcop_sleep;
536
537 fc->dev_type = FC_SKY_OLD;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700538 info("found the vp310 (aka mt312) at i2c address: 0x%02x",skystar23_samsung_tbdu18132_config.demod_address);
539 }
540
541 if (fc->fe == NULL) {
542 err("no frontend driver found for this B2C2/FlexCop adapter");
543 return -ENODEV;
544 } else {
545 if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) {
546 err("frontend registration failed!");
Andrew de Quinceyf52a8382006-08-08 09:10:09 -0300547 dvb_frontend_detach(fc->fe);
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700548 fc->fe = NULL;
549 return -EINVAL;
550 }
551 }
552 fc->init_state |= FC_STATE_FE_INIT;
553 return 0;
554}
555
556void flexcop_frontend_exit(struct flexcop_device *fc)
557{
Andrew de Quincey2bfe0312006-08-08 09:10:08 -0300558 if (fc->init_state & FC_STATE_FE_INIT) {
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700559 dvb_unregister_frontend(fc->fe);
Andrew de Quinceyf52a8382006-08-08 09:10:09 -0300560 dvb_frontend_detach(fc->fe);
Andrew de Quincey2bfe0312006-08-08 09:10:08 -0300561 }
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700562
563 fc->init_state &= ~FC_STATE_FE_INIT;
564}