blob: 46d6f5d8cd1c78dabdacf5a6e9cfa61c8e2e0588 [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
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300186 if (params->frequency < 1500000)
187 buf[3] |= 0x10;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700188
Patrick Boettcherdea74862006-05-14 05:01:31 -0300189 if (fe->ops.i2c_gate_ctrl)
190 fe->ops.i2c_gate_ctrl(fe, 1);
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300191 if (i2c_transfer(&fc->fc_i2c_adap[0].i2c_adap, &msg, 1) != 1)
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700192 return -EIO;
193 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);
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300343 if (i2c_transfer(&fc->fc_i2c_adap[0].i2c_adap, &msg, 1) != 1)
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700344 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]);
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300392 ret = fc->i2c_request(&fc->fc_i2c_adap[2],
393 FC_WRITE, 0x61, buf[0], &buf[1], 3);
Andrew de Quincey56e03142006-04-18 17:47:12 -0300394 deb_tuner("tuner write returned: %d\n",ret);
395
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300396 return ret;
Andrew de Quincey56e03142006-04-18 17:47:12 -0300397}
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700398
399static u8 alps_tdee4_stv0297_inittab[] = {
400 0x80, 0x01,
401 0x80, 0x00,
402 0x81, 0x01,
403 0x81, 0x00,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300404 0x00, 0x48,
405 0x01, 0x58,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700406 0x03, 0x00,
407 0x04, 0x00,
408 0x07, 0x00,
409 0x08, 0x00,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700410 0x30, 0xff,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300411 0x31, 0x9d,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700412 0x32, 0xff,
413 0x33, 0x00,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300414 0x34, 0x29,
415 0x35, 0x55,
416 0x36, 0x80,
417 0x37, 0x6e,
418 0x38, 0x9c,
419 0x40, 0x1a,
420 0x41, 0xfe,
421 0x42, 0x33,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700422 0x43, 0x00,
423 0x44, 0xff,
424 0x45, 0x00,
425 0x46, 0x00,
426 0x49, 0x04,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300427 0x4a, 0x51,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700428 0x4b, 0xf8,
429 0x52, 0x30,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300430 0x53, 0x06,
431 0x59, 0x06,
432 0x5a, 0x5e,
433 0x5b, 0x04,
434 0x61, 0x49,
435 0x62, 0x0a,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700436 0x70, 0xff,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300437 0x71, 0x04,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700438 0x72, 0x00,
439 0x73, 0x00,
440 0x74, 0x0c,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300441 0x80, 0x20,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700442 0x81, 0x00,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300443 0x82, 0x30,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700444 0x83, 0x00,
445 0x84, 0x04,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300446 0x85, 0x22,
447 0x86, 0x08,
448 0x87, 0x1b,
449 0x88, 0x00,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700450 0x89, 0x00,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300451 0x90, 0x00,
452 0x91, 0x04,
453 0xa0, 0x86,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700454 0xa1, 0x00,
455 0xa2, 0x00,
456 0xb0, 0x91,
457 0xb1, 0x0b,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300458 0xc0, 0x5b,
459 0xc1, 0x10,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700460 0xc2, 0x12,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300461 0xd0, 0x02,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700462 0xd1, 0x00,
463 0xd2, 0x00,
464 0xd3, 0x00,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300465 0xd4, 0x02,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700466 0xd5, 0x00,
467 0xde, 0x00,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300468 0xdf, 0x01,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700469 0xff, 0xff,
470};
471
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700472static struct stv0297_config alps_tdee4_stv0297_config = {
473 .demod_address = 0x1c,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700474 .inittab = alps_tdee4_stv0297_inittab,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700475// .invert = 1,
476// .pll_set = alps_tdee4_stv0297_pll_set,
477};
478
479/* try to figure out the frontend, each card/box can have on of the following list */
480int flexcop_frontend_init(struct flexcop_device *fc)
481{
Jesper Juhl6a5bdd32006-01-09 15:25:23 -0200482 struct dvb_frontend_ops *ops;
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300483 struct i2c_adapter *i2c = &fc->fc_i2c_adap[0].i2c_adap;
Jesper Juhl6a5bdd32006-01-09 15:25:23 -0200484
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700485 /* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300486 fc->fe = dvb_attach(stv0299_attach, &samsung_tbmu24112_config, i2c);
487 if (fc->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -0300488 ops = &fc->fe->ops;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700489
Andrew de Quincey56e03142006-04-18 17:47:12 -0300490 ops->tuner_ops.set_params = samsung_tbmu24112_tuner_set_params;
491
Jesper Juhl6a5bdd32006-01-09 15:25:23 -0200492 ops->set_voltage = flexcop_set_voltage;
493
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300494 fc->fe_sleep = ops->sleep;
495 ops->sleep = flexcop_sleep;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700496
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300497 fc->dev_type = FC_SKY;
498 goto fe_found;
499 }
500
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700501 /* try the air dvb-t (mt352/Samsung tdtc9251dh0(??)) */
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300502 fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, i2c);
503 if (fc->fe != NULL) {
504 fc->dev_type = FC_AIR_DVB;
Patrick Boettcherdea74862006-05-14 05:01:31 -0300505 fc->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs;
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300506 goto fe_found;
507 }
508
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700509 /* try the air atsc 2nd generation (nxt2002) */
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300510 fc->fe = dvb_attach(nxt200x_attach, &samsung_tbmv_config, i2c);
511 if (fc->fe != NULL) {
512 fc->dev_type = FC_AIR_ATSC2;
Michael Krufky47a99912007-06-12 16:10:51 -0300513 dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL, DVB_PLL_SAMSUNG_TBMV);
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300514 goto fe_found;
515 }
516
517 fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, i2c);
518 if (fc->fe != NULL) {
519 fc->dev_type = FC_AIR_ATSC3;
520 dvb_attach(simple_tuner_attach, fc->fe, i2c, 0x61,
521 TUNER_LG_TDVS_H06XF);
522 goto fe_found;
523 }
524
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700525 /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300526 fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, i2c);
527 if (fc->fe != NULL) {
528 fc->dev_type = FC_AIR_ATSC1;
529 goto fe_found;
530 }
531
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700532 /* try the cable dvb (stv0297) */
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300533 fc->fe = dvb_attach(stv0297_attach, &alps_tdee4_stv0297_config, i2c);
534 if (fc->fe != NULL) {
535 fc->dev_type = FC_CABLE;
Patrick Boettcherdea74862006-05-14 05:01:31 -0300536 fc->fe->ops.tuner_ops.set_params = alps_tdee4_stv0297_tuner_set_params;
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300537 goto fe_found;
538 }
539
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700540 /* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300541 fc->fe = dvb_attach(vp310_mt312_attach,
542 &skystar23_samsung_tbdu18132_config, i2c);
543 if (fc->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -0300544 ops = &fc->fe->ops;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700545
Andrew de Quincey56e03142006-04-18 17:47:12 -0300546 ops->tuner_ops.set_params = skystar23_samsung_tbdu18132_tuner_set_params;
547
Jesper Juhl6a5bdd32006-01-09 15:25:23 -0200548 ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
549 ops->diseqc_send_burst = flexcop_diseqc_send_burst;
550 ops->set_tone = flexcop_set_tone;
551 ops->set_voltage = flexcop_set_voltage;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700552
Jesper Juhl6a5bdd32006-01-09 15:25:23 -0200553 fc->fe_sleep = ops->sleep;
554 ops->sleep = flexcop_sleep;
555
556 fc->dev_type = FC_SKY_OLD;
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300557 goto fe_found;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700558 }
559
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300560 err("no frontend driver found for this B2C2/FlexCop adapter");
561 return -ENODEV;
562
563fe_found:
564 info("found '%s' .", fc->fe->ops.info.name);
565 if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) {
566 err("frontend registration failed!");
567 ops = &fc->fe->ops;
568 if (ops->release != NULL)
569 ops->release(fc->fe);
570 fc->fe = NULL;
571 return -EINVAL;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700572 }
573 fc->init_state |= FC_STATE_FE_INIT;
574 return 0;
575}
576
577void flexcop_frontend_exit(struct flexcop_device *fc)
578{
Andrew de Quincey2bfe0312006-08-08 09:10:08 -0300579 if (fc->init_state & FC_STATE_FE_INIT) {
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700580 dvb_unregister_frontend(fc->fe);
Andrew de Quinceyf52a8382006-08-08 09:10:09 -0300581 dvb_frontend_detach(fc->fe);
Andrew de Quincey2bfe0312006-08-08 09:10:08 -0300582 }
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700583
584 fc->init_state &= ~FC_STATE_FE_INIT;
585}