blob: 6759c3ad234ace8b31f2f72ce363f0fb50c766c4 [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
Patrick Boettcherc9dd82c2008-03-29 21:28:07 -030022#include "cx24123.h"
23#include "cx24113.h"
24
25#include "isl6421.h"
26
Johannes Stezenbach2add87a2005-05-16 21:54:10 -070027/* lnb control */
28
29static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
30{
31 struct flexcop_device *fc = fe->dvb->priv;
32 flexcop_ibi_value v;
33 deb_tuner("polarity/voltage = %u\n", voltage);
34
35 v = fc->read_ibi_reg(fc, misc_204);
36 switch (voltage) {
37 case SEC_VOLTAGE_OFF:
38 v.misc_204.ACPI1_sig = 1;
39 break;
40 case SEC_VOLTAGE_13:
41 v.misc_204.ACPI1_sig = 0;
42 v.misc_204.LNB_L_H_sig = 0;
43 break;
44 case SEC_VOLTAGE_18:
45 v.misc_204.ACPI1_sig = 0;
46 v.misc_204.LNB_L_H_sig = 1;
47 break;
48 default:
49 err("unknown SEC_VOLTAGE value");
50 return -EINVAL;
51 }
52 return fc->write_ibi_reg(fc, misc_204, v);
53}
54
55static int flexcop_sleep(struct dvb_frontend* fe)
56{
57 struct flexcop_device *fc = fe->dvb->priv;
58/* flexcop_ibi_value v = fc->read_ibi_reg(fc,misc_204); */
59
60 if (fc->fe_sleep)
61 return fc->fe_sleep(fe);
62
63/* v.misc_204.ACPI3_sig = 1;
64 fc->write_ibi_reg(fc,misc_204,v);*/
65
66 return 0;
67}
68
69static int flexcop_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
70{
71 /* u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc }; */
72 struct flexcop_device *fc = fe->dvb->priv;
73 flexcop_ibi_value v;
74 u16 ax;
75 v.raw = 0;
76
77 deb_tuner("tone = %u\n",tone);
78
79 switch (tone) {
80 case SEC_TONE_ON:
81 ax = 0x01ff;
82 break;
83 case SEC_TONE_OFF:
84 ax = 0;
85 break;
86 default:
87 err("unknown SEC_TONE value");
88 return -EINVAL;
89 }
90
91 v.lnb_switch_freq_200.LNB_CTLPrescaler_sig = 1; /* divide by 2 */
92
Johannes Stezenbach958706c2005-05-16 21:54:19 -070093 v.lnb_switch_freq_200.LNB_CTLHighCount_sig = ax;
94 v.lnb_switch_freq_200.LNB_CTLLowCount_sig = ax == 0 ? 0x1ff : ax;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -070095
96 return fc->write_ibi_reg(fc,lnb_switch_freq_200,v);
97}
98
99static void flexcop_diseqc_send_bit(struct dvb_frontend* fe, int data)
100{
101 flexcop_set_tone(fe, SEC_TONE_ON);
102 udelay(data ? 500 : 1000);
103 flexcop_set_tone(fe, SEC_TONE_OFF);
104 udelay(data ? 1000 : 500);
105}
106
107static void flexcop_diseqc_send_byte(struct dvb_frontend* fe, int data)
108{
109 int i, par = 1, d;
110
111 for (i = 7; i >= 0; i--) {
112 d = (data >> i) & 1;
113 par ^= d;
114 flexcop_diseqc_send_bit(fe, d);
115 }
116
117 flexcop_diseqc_send_bit(fe, par);
118}
119
120static int flexcop_send_diseqc_msg(struct dvb_frontend* fe, int len, u8 *msg, unsigned long burst)
121{
122 int i;
123
124 flexcop_set_tone(fe, SEC_TONE_OFF);
125 mdelay(16);
126
127 for (i = 0; i < len; i++)
128 flexcop_diseqc_send_byte(fe,msg[i]);
129
130 mdelay(16);
131
132 if (burst != -1) {
133 if (burst)
134 flexcop_diseqc_send_byte(fe, 0xff);
135 else {
136 flexcop_set_tone(fe, SEC_TONE_ON);
137 udelay(12500);
138 flexcop_set_tone(fe, SEC_TONE_OFF);
139 }
140 msleep(20);
141 }
142 return 0;
143}
144
145static int flexcop_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
146{
147 return flexcop_send_diseqc_msg(fe, cmd->msg_len, cmd->msg, 0);
148}
149
150static int flexcop_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
151{
152 return flexcop_send_diseqc_msg(fe, 0, NULL, minicmd);
153}
154
155/* dvb-s stv0299 */
156static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
157{
158 u8 aclk = 0;
159 u8 bclk = 0;
160
161 if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
162 else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
163 else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
164 else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
165 else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
166 else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
167
168 stv0299_writereg (fe, 0x13, aclk);
169 stv0299_writereg (fe, 0x14, bclk);
170 stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff);
171 stv0299_writereg (fe, 0x20, (ratio >> 8) & 0xff);
172 stv0299_writereg (fe, 0x21, (ratio ) & 0xf0);
173
174 return 0;
175}
176
Andrew de Quincey56e03142006-04-18 17:47:12 -0300177static int samsung_tbmu24112_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params)
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700178{
179 u8 buf[4];
180 u32 div;
181 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
Andrew de Quincey56e03142006-04-18 17:47:12 -0300182 struct flexcop_device *fc = fe->dvb->priv;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700183
184 div = params->frequency / 125;
185
186 buf[0] = (div >> 8) & 0x7f;
187 buf[1] = div & 0xff;
188 buf[2] = 0x84; /* 0xC4 */
189 buf[3] = 0x08;
190
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300191 if (params->frequency < 1500000)
192 buf[3] |= 0x10;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700193
Patrick Boettcherdea74862006-05-14 05:01:31 -0300194 if (fe->ops.i2c_gate_ctrl)
195 fe->ops.i2c_gate_ctrl(fe, 1);
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300196 if (i2c_transfer(&fc->fc_i2c_adap[0].i2c_adap, &msg, 1) != 1)
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700197 return -EIO;
198 return 0;
199}
200
201static u8 samsung_tbmu24112_inittab[] = {
202 0x01, 0x15,
203 0x02, 0x30,
204 0x03, 0x00,
205 0x04, 0x7D,
206 0x05, 0x35,
207 0x06, 0x02,
208 0x07, 0x00,
209 0x08, 0xC3,
210 0x0C, 0x00,
211 0x0D, 0x81,
212 0x0E, 0x23,
213 0x0F, 0x12,
214 0x10, 0x7E,
215 0x11, 0x84,
216 0x12, 0xB9,
217 0x13, 0x88,
218 0x14, 0x89,
219 0x15, 0xC9,
220 0x16, 0x00,
221 0x17, 0x5C,
222 0x18, 0x00,
223 0x19, 0x00,
224 0x1A, 0x00,
225 0x1C, 0x00,
226 0x1D, 0x00,
227 0x1E, 0x00,
228 0x1F, 0x3A,
229 0x20, 0x2E,
230 0x21, 0x80,
231 0x22, 0xFF,
232 0x23, 0xC1,
233 0x28, 0x00,
234 0x29, 0x1E,
235 0x2A, 0x14,
236 0x2B, 0x0F,
237 0x2C, 0x09,
238 0x2D, 0x05,
239 0x31, 0x1F,
240 0x32, 0x19,
241 0x33, 0xFE,
242 0x34, 0x93,
243 0xff, 0xff,
244};
245
246static struct stv0299_config samsung_tbmu24112_config = {
247 .demod_address = 0x68,
248 .inittab = samsung_tbmu24112_inittab,
249 .mclk = 88000000UL,
250 .invert = 0,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700251 .skip_reinit = 0,
252 .lock_output = STV0229_LOCKOUTPUT_LK,
253 .volt13_op0_op1 = STV0299_VOLT13_OP1,
254 .min_delay_ms = 100,
255 .set_symbol_rate = samsung_tbmu24112_set_symbol_rate,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700256};
257
258/* dvb-t mt352 */
259static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
260{
261 static u8 mt352_clock_config [] = { 0x89, 0x18, 0x2d };
262 static u8 mt352_reset [] = { 0x50, 0x80 };
263 static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
264 static u8 mt352_agc_cfg [] = { 0x67, 0x28, 0xa1 };
265 static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
266
267 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
268 udelay(2000);
269 mt352_write(fe, mt352_reset, sizeof(mt352_reset));
270 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
271
272 mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
273 mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
274
275 return 0;
276}
277
Andrew de Quincey56e03142006-04-18 17:47:12 -0300278static 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 -0700279{
280 u32 div;
281 unsigned char bs = 0;
282
Andrew de Quincey56e03142006-04-18 17:47:12 -0300283 if (buf_len < 5)
284 return -EINVAL;
285
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700286 #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
287 div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
288
289 if (params->frequency >= 48000000 && params->frequency <= 154000000) bs = 0x09;
290 if (params->frequency >= 161000000 && params->frequency <= 439000000) bs = 0x0a;
291 if (params->frequency >= 447000000 && params->frequency <= 863000000) bs = 0x08;
292
Andrew de Quincey56e03142006-04-18 17:47:12 -0300293 pllbuf[0] = 0x61;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700294 pllbuf[1] = div >> 8;
295 pllbuf[2] = div & 0xff;
296 pllbuf[3] = 0xcc;
297 pllbuf[4] = bs;
298
Andrew de Quincey56e03142006-04-18 17:47:12 -0300299 return 5;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700300}
301
302static struct mt352_config samsung_tdtc9251dh0_config = {
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700303 .demod_address = 0x0f,
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700304 .demod_init = samsung_tdtc9251dh0_demod_init,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700305};
306
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700307static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700308{
309 struct flexcop_device *fc = fe->dvb->priv;
310 return request_firmware(fw, name, fc->dev);
311}
312
Michael Krufkyc0b11b92005-11-08 21:35:32 -0800313static struct lgdt330x_config air2pc_atsc_hd5000_config = {
314 .demod_address = 0x59,
315 .demod_chip = LGDT3303,
316 .serial_mpeg = 0x04,
Michael Krufkyc0b11b92005-11-08 21:35:32 -0800317 .clock_polarity_flip = 1,
318};
319
Michael Krufky46365f32006-01-23 09:52:39 -0200320static struct nxt200x_config samsung_tbmv_config = {
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700321 .demod_address = 0x0a,
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700322};
323
324static struct bcm3510_config air2pc_atsc_first_gen_config = {
325 .demod_address = 0x0f,
326 .request_firmware = flexcop_fe_request_firmware,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700327};
328
Andrew de Quincey56e03142006-04-18 17:47:12 -0300329static int skystar23_samsung_tbdu18132_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params)
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700330{
331 u8 buf[4];
332 u32 div;
333 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
334 struct flexcop_device *fc = fe->dvb->priv;
335
336 div = (params->frequency + (125/2)) / 125;
337
338 buf[0] = (div >> 8) & 0x7f;
339 buf[1] = (div >> 0) & 0xff;
340 buf[2] = 0x84 | ((div >> 10) & 0x60);
341 buf[3] = 0x80;
342
343 if (params->frequency < 1550000)
344 buf[3] |= 0x02;
345
Patrick Boettcherdea74862006-05-14 05:01:31 -0300346 if (fe->ops.i2c_gate_ctrl)
347 fe->ops.i2c_gate_ctrl(fe, 1);
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300348 if (i2c_transfer(&fc->fc_i2c_adap[0].i2c_adap, &msg, 1) != 1)
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700349 return -EIO;
350 return 0;
351}
352
353static struct mt312_config skystar23_samsung_tbdu18132_config = {
354
355 .demod_address = 0x0e,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700356};
357
Adrian Bunkdd00b1e2006-05-29 12:31:44 -0300358static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe,
359 struct dvb_frontend_parameters *fep)
Andrew de Quincey56e03142006-04-18 17:47:12 -0300360{
361 struct flexcop_device *fc = fe->dvb->priv;
362 u8 buf[4];
363 u16 div;
364 int ret;
365
366/* 62.5 kHz * 10 */
367#define REF_FREQ 625
368#define FREQ_OFFSET 36125
369
370 div = ((fep->frequency/1000 + FREQ_OFFSET ) * 10) / REF_FREQ; // 4 MHz = 4000 KHz
371
372 buf[0] = (u8)( div >> 8) & 0x7f;
373 buf[1] = (u8) div & 0xff;
374
375/* F(osc) = N * Reference Freq. (62.5 kHz)
376 * byte 2 : 0 N14 N13 N12 N11 N10 N9 N8
377 * byte 3 : N7 N6 N5 N4 N3 N2 N1 N0
378 * byte 4 : 1 * * AGD R3 R2 R1 R0
379 * byte 5 : C1 * RE RTS BS4 BS3 BS2 BS1
380 * AGD = 1, R3 R2 R1 R0 = 0 1 0 1 => byte 4 = 1**10101 = 0x95 */
381 buf[2] = 0x95;
382
383// Range(MHz) C1 * RE RTS BS4 BS3 BS2 BS1 Byte 5
384// 47 - 153 0 * 0 0 0 0 0 1 0x01
385// 153 - 430 0 * 0 0 0 0 1 0 0x02
386// 430 - 822 0 * 0 0 1 0 0 0 0x08
387// 822 - 862 1 * 0 0 1 0 0 0 0x88
388
389 if (fep->frequency <= 153000000) buf[3] = 0x01;
390 else if (fep->frequency <= 430000000) buf[3] = 0x02;
391 else if (fep->frequency <= 822000000) buf[3] = 0x08;
392 else buf[3] = 0x88;
393
Patrick Boettcherdea74862006-05-14 05:01:31 -0300394 if (fe->ops.i2c_gate_ctrl)
Antti Seppälä9d85d772006-12-20 11:10:35 -0300395 fe->ops.i2c_gate_ctrl(fe, 0);
Andrew de Quincey56e03142006-04-18 17:47:12 -0300396 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 -0300397 ret = fc->i2c_request(&fc->fc_i2c_adap[2],
398 FC_WRITE, 0x61, buf[0], &buf[1], 3);
Andrew de Quincey56e03142006-04-18 17:47:12 -0300399 deb_tuner("tuner write returned: %d\n",ret);
400
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300401 return ret;
Andrew de Quincey56e03142006-04-18 17:47:12 -0300402}
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700403
404static u8 alps_tdee4_stv0297_inittab[] = {
405 0x80, 0x01,
406 0x80, 0x00,
407 0x81, 0x01,
408 0x81, 0x00,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300409 0x00, 0x48,
410 0x01, 0x58,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700411 0x03, 0x00,
412 0x04, 0x00,
413 0x07, 0x00,
414 0x08, 0x00,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700415 0x30, 0xff,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300416 0x31, 0x9d,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700417 0x32, 0xff,
418 0x33, 0x00,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300419 0x34, 0x29,
420 0x35, 0x55,
421 0x36, 0x80,
422 0x37, 0x6e,
423 0x38, 0x9c,
424 0x40, 0x1a,
425 0x41, 0xfe,
426 0x42, 0x33,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700427 0x43, 0x00,
428 0x44, 0xff,
429 0x45, 0x00,
430 0x46, 0x00,
431 0x49, 0x04,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300432 0x4a, 0x51,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700433 0x4b, 0xf8,
434 0x52, 0x30,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300435 0x53, 0x06,
436 0x59, 0x06,
437 0x5a, 0x5e,
438 0x5b, 0x04,
439 0x61, 0x49,
440 0x62, 0x0a,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700441 0x70, 0xff,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300442 0x71, 0x04,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700443 0x72, 0x00,
444 0x73, 0x00,
445 0x74, 0x0c,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300446 0x80, 0x20,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700447 0x81, 0x00,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300448 0x82, 0x30,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700449 0x83, 0x00,
450 0x84, 0x04,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300451 0x85, 0x22,
452 0x86, 0x08,
453 0x87, 0x1b,
454 0x88, 0x00,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700455 0x89, 0x00,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300456 0x90, 0x00,
457 0x91, 0x04,
458 0xa0, 0x86,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700459 0xa1, 0x00,
460 0xa2, 0x00,
461 0xb0, 0x91,
462 0xb1, 0x0b,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300463 0xc0, 0x5b,
464 0xc1, 0x10,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700465 0xc2, 0x12,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300466 0xd0, 0x02,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700467 0xd1, 0x00,
468 0xd2, 0x00,
469 0xd3, 0x00,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300470 0xd4, 0x02,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700471 0xd5, 0x00,
472 0xde, 0x00,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300473 0xdf, 0x01,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700474 0xff, 0xff,
475};
476
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700477static struct stv0297_config alps_tdee4_stv0297_config = {
478 .demod_address = 0x1c,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700479 .inittab = alps_tdee4_stv0297_inittab,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700480// .invert = 1,
481// .pll_set = alps_tdee4_stv0297_pll_set,
482};
483
Patrick Boettcherc9dd82c2008-03-29 21:28:07 -0300484
485static struct cx24123_config skystar2_rev2_8_cx24123_config = {
486 .demod_address = 0x55,
487 .dont_use_pll = 1,
488 .agc_callback = cx24113_agc_callback,
489};
490
491static const struct cx24113_config skystar2_rev2_8_cx24113_config = {
492 .i2c_addr = 0x54,
493 .xtal_khz = 10111,
494};
495
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700496/* try to figure out the frontend, each card/box can have on of the following list */
497int flexcop_frontend_init(struct flexcop_device *fc)
498{
Jesper Juhl6a5bdd32006-01-09 15:25:23 -0200499 struct dvb_frontend_ops *ops;
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300500 struct i2c_adapter *i2c = &fc->fc_i2c_adap[0].i2c_adap;
Patrick Boettcherc9dd82c2008-03-29 21:28:07 -0300501 struct i2c_adapter *i2c_tuner;
502
503 /* try the sky v2.8 (cx24123, isl6421) */
504 fc->fe = dvb_attach(cx24123_attach,
505 &skystar2_rev2_8_cx24123_config, i2c);
506 if (fc->fe != NULL) {
507 i2c_tuner = cx24123_get_tuner_i2c_adapter(fc->fe);
508 if (i2c_tuner != NULL) {
509 if (dvb_attach(cx24113_attach, fc->fe,
510 &skystar2_rev2_8_cx24113_config,
511 i2c_tuner) == NULL)
512 err("CX24113 could NOT be attached");
513 else
514 info("CX24113 successfully attached");
515 }
516
517 fc->dev_type = FC_SKY_REV28;
518
519 fc->fc_i2c_adap[2].no_base_addr = 1;
520 if (dvb_attach(isl6421_attach, fc->fe,
521 &fc->fc_i2c_adap[2].i2c_adap, 0x08, 0, 0) == NULL)
522 err("ISL6421 could NOT be attached");
523 else
524 info("ISL6421 successfully attached");
525
526 /* TODO on i2c_adap[1] addr 0x11 (EEPROM) there seems to be an
527 * IR-receiver (PIC16F818) - but the card has no input for
528 * that ??? */
529
530 goto fe_found;
531 }
Jesper Juhl6a5bdd32006-01-09 15:25:23 -0200532
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700533 /* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300534 fc->fe = dvb_attach(stv0299_attach, &samsung_tbmu24112_config, i2c);
535 if (fc->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -0300536 ops = &fc->fe->ops;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700537
Andrew de Quincey56e03142006-04-18 17:47:12 -0300538 ops->tuner_ops.set_params = samsung_tbmu24112_tuner_set_params;
539
Jesper Juhl6a5bdd32006-01-09 15:25:23 -0200540 ops->set_voltage = flexcop_set_voltage;
541
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300542 fc->fe_sleep = ops->sleep;
543 ops->sleep = flexcop_sleep;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700544
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300545 fc->dev_type = FC_SKY;
546 goto fe_found;
547 }
548
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700549 /* try the air dvb-t (mt352/Samsung tdtc9251dh0(??)) */
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300550 fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, i2c);
551 if (fc->fe != NULL) {
552 fc->dev_type = FC_AIR_DVB;
Patrick Boettcherdea74862006-05-14 05:01:31 -0300553 fc->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs;
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300554 goto fe_found;
555 }
556
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700557 /* try the air atsc 2nd generation (nxt2002) */
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300558 fc->fe = dvb_attach(nxt200x_attach, &samsung_tbmv_config, i2c);
559 if (fc->fe != NULL) {
560 fc->dev_type = FC_AIR_ATSC2;
Michael Krufky47a99912007-06-12 16:10:51 -0300561 dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL, DVB_PLL_SAMSUNG_TBMV);
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300562 goto fe_found;
563 }
564
565 fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, i2c);
566 if (fc->fe != NULL) {
567 fc->dev_type = FC_AIR_ATSC3;
568 dvb_attach(simple_tuner_attach, fc->fe, i2c, 0x61,
569 TUNER_LG_TDVS_H06XF);
570 goto fe_found;
571 }
572
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700573 /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300574 fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, i2c);
575 if (fc->fe != NULL) {
576 fc->dev_type = FC_AIR_ATSC1;
577 goto fe_found;
578 }
579
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700580 /* try the cable dvb (stv0297) */
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300581 fc->fe = dvb_attach(stv0297_attach, &alps_tdee4_stv0297_config, i2c);
582 if (fc->fe != NULL) {
583 fc->dev_type = FC_CABLE;
Patrick Boettcherdea74862006-05-14 05:01:31 -0300584 fc->fe->ops.tuner_ops.set_params = alps_tdee4_stv0297_tuner_set_params;
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300585 goto fe_found;
586 }
587
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700588 /* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300589 fc->fe = dvb_attach(vp310_mt312_attach,
590 &skystar23_samsung_tbdu18132_config, i2c);
591 if (fc->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -0300592 ops = &fc->fe->ops;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700593
Andrew de Quincey56e03142006-04-18 17:47:12 -0300594 ops->tuner_ops.set_params = skystar23_samsung_tbdu18132_tuner_set_params;
595
Jesper Juhl6a5bdd32006-01-09 15:25:23 -0200596 ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
597 ops->diseqc_send_burst = flexcop_diseqc_send_burst;
598 ops->set_tone = flexcop_set_tone;
599 ops->set_voltage = flexcop_set_voltage;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700600
Jesper Juhl6a5bdd32006-01-09 15:25:23 -0200601 fc->fe_sleep = ops->sleep;
602 ops->sleep = flexcop_sleep;
603
604 fc->dev_type = FC_SKY_OLD;
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300605 goto fe_found;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700606 }
607
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300608 err("no frontend driver found for this B2C2/FlexCop adapter");
609 return -ENODEV;
610
611fe_found:
612 info("found '%s' .", fc->fe->ops.info.name);
613 if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) {
614 err("frontend registration failed!");
615 ops = &fc->fe->ops;
616 if (ops->release != NULL)
617 ops->release(fc->fe);
618 fc->fe = NULL;
619 return -EINVAL;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700620 }
621 fc->init_state |= FC_STATE_FE_INIT;
622 return 0;
623}
624
625void flexcop_frontend_exit(struct flexcop_device *fc)
626{
Andrew de Quincey2bfe0312006-08-08 09:10:08 -0300627 if (fc->init_state & FC_STATE_FE_INIT) {
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700628 dvb_unregister_frontend(fc->fe);
Andrew de Quinceyf52a8382006-08-08 09:10:09 -0300629 dvb_frontend_detach(fc->fe);
Andrew de Quincey2bfe0312006-08-08 09:10:08 -0300630 }
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700631
632 fc->init_state &= ~FC_STATE_FE_INIT;
633}