blob: f9d087669d5db3dce7de713182e50eec8bdcc6d6 [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 Boettcherca19aaa2008-04-13 15:49:22 -030022#include "s5h1420.h"
23#include "itd1000.h"
24
Patrick Boettcherc9dd82c2008-03-29 21:28:07 -030025#include "cx24123.h"
26#include "cx24113.h"
27
28#include "isl6421.h"
29
Johannes Stezenbach2add87a2005-05-16 21:54:10 -070030/* lnb control */
31
32static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
33{
34 struct flexcop_device *fc = fe->dvb->priv;
35 flexcop_ibi_value v;
36 deb_tuner("polarity/voltage = %u\n", voltage);
37
38 v = fc->read_ibi_reg(fc, misc_204);
39 switch (voltage) {
40 case SEC_VOLTAGE_OFF:
41 v.misc_204.ACPI1_sig = 1;
42 break;
43 case SEC_VOLTAGE_13:
44 v.misc_204.ACPI1_sig = 0;
45 v.misc_204.LNB_L_H_sig = 0;
46 break;
47 case SEC_VOLTAGE_18:
48 v.misc_204.ACPI1_sig = 0;
49 v.misc_204.LNB_L_H_sig = 1;
50 break;
51 default:
52 err("unknown SEC_VOLTAGE value");
53 return -EINVAL;
54 }
55 return fc->write_ibi_reg(fc, misc_204, v);
56}
57
58static int flexcop_sleep(struct dvb_frontend* fe)
59{
60 struct flexcop_device *fc = fe->dvb->priv;
61/* flexcop_ibi_value v = fc->read_ibi_reg(fc,misc_204); */
62
63 if (fc->fe_sleep)
64 return fc->fe_sleep(fe);
65
66/* v.misc_204.ACPI3_sig = 1;
67 fc->write_ibi_reg(fc,misc_204,v);*/
68
69 return 0;
70}
71
72static int flexcop_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
73{
74 /* u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc }; */
75 struct flexcop_device *fc = fe->dvb->priv;
76 flexcop_ibi_value v;
77 u16 ax;
78 v.raw = 0;
79
80 deb_tuner("tone = %u\n",tone);
81
82 switch (tone) {
83 case SEC_TONE_ON:
84 ax = 0x01ff;
85 break;
86 case SEC_TONE_OFF:
87 ax = 0;
88 break;
89 default:
90 err("unknown SEC_TONE value");
91 return -EINVAL;
92 }
93
94 v.lnb_switch_freq_200.LNB_CTLPrescaler_sig = 1; /* divide by 2 */
95
Johannes Stezenbach958706c2005-05-16 21:54:19 -070096 v.lnb_switch_freq_200.LNB_CTLHighCount_sig = ax;
97 v.lnb_switch_freq_200.LNB_CTLLowCount_sig = ax == 0 ? 0x1ff : ax;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -070098
99 return fc->write_ibi_reg(fc,lnb_switch_freq_200,v);
100}
101
102static void flexcop_diseqc_send_bit(struct dvb_frontend* fe, int data)
103{
104 flexcop_set_tone(fe, SEC_TONE_ON);
105 udelay(data ? 500 : 1000);
106 flexcop_set_tone(fe, SEC_TONE_OFF);
107 udelay(data ? 1000 : 500);
108}
109
110static void flexcop_diseqc_send_byte(struct dvb_frontend* fe, int data)
111{
112 int i, par = 1, d;
113
114 for (i = 7; i >= 0; i--) {
115 d = (data >> i) & 1;
116 par ^= d;
117 flexcop_diseqc_send_bit(fe, d);
118 }
119
120 flexcop_diseqc_send_bit(fe, par);
121}
122
123static int flexcop_send_diseqc_msg(struct dvb_frontend* fe, int len, u8 *msg, unsigned long burst)
124{
125 int i;
126
127 flexcop_set_tone(fe, SEC_TONE_OFF);
128 mdelay(16);
129
130 for (i = 0; i < len; i++)
131 flexcop_diseqc_send_byte(fe,msg[i]);
132
133 mdelay(16);
134
135 if (burst != -1) {
136 if (burst)
137 flexcop_diseqc_send_byte(fe, 0xff);
138 else {
139 flexcop_set_tone(fe, SEC_TONE_ON);
140 udelay(12500);
141 flexcop_set_tone(fe, SEC_TONE_OFF);
142 }
143 msleep(20);
144 }
145 return 0;
146}
147
148static int flexcop_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
149{
150 return flexcop_send_diseqc_msg(fe, cmd->msg_len, cmd->msg, 0);
151}
152
153static int flexcop_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
154{
155 return flexcop_send_diseqc_msg(fe, 0, NULL, minicmd);
156}
157
158/* dvb-s stv0299 */
159static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
160{
161 u8 aclk = 0;
162 u8 bclk = 0;
163
164 if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
165 else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
166 else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
167 else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
168 else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
169 else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
170
171 stv0299_writereg (fe, 0x13, aclk);
172 stv0299_writereg (fe, 0x14, bclk);
173 stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff);
174 stv0299_writereg (fe, 0x20, (ratio >> 8) & 0xff);
175 stv0299_writereg (fe, 0x21, (ratio ) & 0xf0);
176
177 return 0;
178}
179
Andrew de Quincey56e03142006-04-18 17:47:12 -0300180static int samsung_tbmu24112_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params)
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700181{
182 u8 buf[4];
183 u32 div;
184 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
Andrew de Quincey56e03142006-04-18 17:47:12 -0300185 struct flexcop_device *fc = fe->dvb->priv;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700186
187 div = params->frequency / 125;
188
189 buf[0] = (div >> 8) & 0x7f;
190 buf[1] = div & 0xff;
191 buf[2] = 0x84; /* 0xC4 */
192 buf[3] = 0x08;
193
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300194 if (params->frequency < 1500000)
195 buf[3] |= 0x10;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700196
Patrick Boettcherdea74862006-05-14 05:01:31 -0300197 if (fe->ops.i2c_gate_ctrl)
198 fe->ops.i2c_gate_ctrl(fe, 1);
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300199 if (i2c_transfer(&fc->fc_i2c_adap[0].i2c_adap, &msg, 1) != 1)
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700200 return -EIO;
201 return 0;
202}
203
204static u8 samsung_tbmu24112_inittab[] = {
205 0x01, 0x15,
206 0x02, 0x30,
207 0x03, 0x00,
208 0x04, 0x7D,
209 0x05, 0x35,
210 0x06, 0x02,
211 0x07, 0x00,
212 0x08, 0xC3,
213 0x0C, 0x00,
214 0x0D, 0x81,
215 0x0E, 0x23,
216 0x0F, 0x12,
217 0x10, 0x7E,
218 0x11, 0x84,
219 0x12, 0xB9,
220 0x13, 0x88,
221 0x14, 0x89,
222 0x15, 0xC9,
223 0x16, 0x00,
224 0x17, 0x5C,
225 0x18, 0x00,
226 0x19, 0x00,
227 0x1A, 0x00,
228 0x1C, 0x00,
229 0x1D, 0x00,
230 0x1E, 0x00,
231 0x1F, 0x3A,
232 0x20, 0x2E,
233 0x21, 0x80,
234 0x22, 0xFF,
235 0x23, 0xC1,
236 0x28, 0x00,
237 0x29, 0x1E,
238 0x2A, 0x14,
239 0x2B, 0x0F,
240 0x2C, 0x09,
241 0x2D, 0x05,
242 0x31, 0x1F,
243 0x32, 0x19,
244 0x33, 0xFE,
245 0x34, 0x93,
246 0xff, 0xff,
247};
248
249static struct stv0299_config samsung_tbmu24112_config = {
250 .demod_address = 0x68,
251 .inittab = samsung_tbmu24112_inittab,
252 .mclk = 88000000UL,
253 .invert = 0,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700254 .skip_reinit = 0,
Oliver Endrissda2c7f62008-04-20 22:13:37 -0300255 .lock_output = STV0299_LOCKOUTPUT_LK,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700256 .volt13_op0_op1 = STV0299_VOLT13_OP1,
257 .min_delay_ms = 100,
258 .set_symbol_rate = samsung_tbmu24112_set_symbol_rate,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700259};
260
261/* dvb-t mt352 */
262static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
263{
264 static u8 mt352_clock_config [] = { 0x89, 0x18, 0x2d };
265 static u8 mt352_reset [] = { 0x50, 0x80 };
266 static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
267 static u8 mt352_agc_cfg [] = { 0x67, 0x28, 0xa1 };
268 static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
269
270 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
271 udelay(2000);
272 mt352_write(fe, mt352_reset, sizeof(mt352_reset));
273 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
274
275 mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
276 mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
277
278 return 0;
279}
280
Andrew de Quincey56e03142006-04-18 17:47:12 -0300281static 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 -0700282{
283 u32 div;
284 unsigned char bs = 0;
285
Andrew de Quincey56e03142006-04-18 17:47:12 -0300286 if (buf_len < 5)
287 return -EINVAL;
288
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700289 #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
290 div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
291
292 if (params->frequency >= 48000000 && params->frequency <= 154000000) bs = 0x09;
293 if (params->frequency >= 161000000 && params->frequency <= 439000000) bs = 0x0a;
294 if (params->frequency >= 447000000 && params->frequency <= 863000000) bs = 0x08;
295
Andrew de Quincey56e03142006-04-18 17:47:12 -0300296 pllbuf[0] = 0x61;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700297 pllbuf[1] = div >> 8;
298 pllbuf[2] = div & 0xff;
299 pllbuf[3] = 0xcc;
300 pllbuf[4] = bs;
301
Andrew de Quincey56e03142006-04-18 17:47:12 -0300302 return 5;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700303}
304
305static struct mt352_config samsung_tdtc9251dh0_config = {
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700306 .demod_address = 0x0f,
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700307 .demod_init = samsung_tdtc9251dh0_demod_init,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700308};
309
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700310static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700311{
312 struct flexcop_device *fc = fe->dvb->priv;
313 return request_firmware(fw, name, fc->dev);
314}
315
Michael Krufkyc0b11b92005-11-08 21:35:32 -0800316static struct lgdt330x_config air2pc_atsc_hd5000_config = {
317 .demod_address = 0x59,
318 .demod_chip = LGDT3303,
319 .serial_mpeg = 0x04,
Michael Krufkyc0b11b92005-11-08 21:35:32 -0800320 .clock_polarity_flip = 1,
321};
322
Michael Krufky46365f32006-01-23 09:52:39 -0200323static struct nxt200x_config samsung_tbmv_config = {
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700324 .demod_address = 0x0a,
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700325};
326
327static struct bcm3510_config air2pc_atsc_first_gen_config = {
328 .demod_address = 0x0f,
329 .request_firmware = flexcop_fe_request_firmware,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700330};
331
Andrew de Quincey56e03142006-04-18 17:47:12 -0300332static int skystar23_samsung_tbdu18132_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params)
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700333{
334 u8 buf[4];
335 u32 div;
336 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
337 struct flexcop_device *fc = fe->dvb->priv;
338
339 div = (params->frequency + (125/2)) / 125;
340
341 buf[0] = (div >> 8) & 0x7f;
342 buf[1] = (div >> 0) & 0xff;
343 buf[2] = 0x84 | ((div >> 10) & 0x60);
344 buf[3] = 0x80;
345
346 if (params->frequency < 1550000)
347 buf[3] |= 0x02;
348
Patrick Boettcherdea74862006-05-14 05:01:31 -0300349 if (fe->ops.i2c_gate_ctrl)
350 fe->ops.i2c_gate_ctrl(fe, 1);
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300351 if (i2c_transfer(&fc->fc_i2c_adap[0].i2c_adap, &msg, 1) != 1)
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700352 return -EIO;
353 return 0;
354}
355
356static struct mt312_config skystar23_samsung_tbdu18132_config = {
357
358 .demod_address = 0x0e,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700359};
360
Adrian Bunkdd00b1e2006-05-29 12:31:44 -0300361static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe,
362 struct dvb_frontend_parameters *fep)
Andrew de Quincey56e03142006-04-18 17:47:12 -0300363{
364 struct flexcop_device *fc = fe->dvb->priv;
365 u8 buf[4];
366 u16 div;
367 int ret;
368
369/* 62.5 kHz * 10 */
370#define REF_FREQ 625
371#define FREQ_OFFSET 36125
372
373 div = ((fep->frequency/1000 + FREQ_OFFSET ) * 10) / REF_FREQ; // 4 MHz = 4000 KHz
374
375 buf[0] = (u8)( div >> 8) & 0x7f;
376 buf[1] = (u8) div & 0xff;
377
378/* F(osc) = N * Reference Freq. (62.5 kHz)
379 * byte 2 : 0 N14 N13 N12 N11 N10 N9 N8
380 * byte 3 : N7 N6 N5 N4 N3 N2 N1 N0
381 * byte 4 : 1 * * AGD R3 R2 R1 R0
382 * byte 5 : C1 * RE RTS BS4 BS3 BS2 BS1
383 * AGD = 1, R3 R2 R1 R0 = 0 1 0 1 => byte 4 = 1**10101 = 0x95 */
384 buf[2] = 0x95;
385
386// Range(MHz) C1 * RE RTS BS4 BS3 BS2 BS1 Byte 5
387// 47 - 153 0 * 0 0 0 0 0 1 0x01
388// 153 - 430 0 * 0 0 0 0 1 0 0x02
389// 430 - 822 0 * 0 0 1 0 0 0 0x08
390// 822 - 862 1 * 0 0 1 0 0 0 0x88
391
392 if (fep->frequency <= 153000000) buf[3] = 0x01;
393 else if (fep->frequency <= 430000000) buf[3] = 0x02;
394 else if (fep->frequency <= 822000000) buf[3] = 0x08;
395 else buf[3] = 0x88;
396
Patrick Boettcherdea74862006-05-14 05:01:31 -0300397 if (fe->ops.i2c_gate_ctrl)
Antti Seppälä9d85d772006-12-20 11:10:35 -0300398 fe->ops.i2c_gate_ctrl(fe, 0);
Andrew de Quincey56e03142006-04-18 17:47:12 -0300399 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 -0300400 ret = fc->i2c_request(&fc->fc_i2c_adap[2],
401 FC_WRITE, 0x61, buf[0], &buf[1], 3);
Andrew de Quincey56e03142006-04-18 17:47:12 -0300402 deb_tuner("tuner write returned: %d\n",ret);
403
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300404 return ret;
Andrew de Quincey56e03142006-04-18 17:47:12 -0300405}
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700406
407static u8 alps_tdee4_stv0297_inittab[] = {
408 0x80, 0x01,
409 0x80, 0x00,
410 0x81, 0x01,
411 0x81, 0x00,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300412 0x00, 0x48,
413 0x01, 0x58,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700414 0x03, 0x00,
415 0x04, 0x00,
416 0x07, 0x00,
417 0x08, 0x00,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700418 0x30, 0xff,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300419 0x31, 0x9d,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700420 0x32, 0xff,
421 0x33, 0x00,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300422 0x34, 0x29,
423 0x35, 0x55,
424 0x36, 0x80,
425 0x37, 0x6e,
426 0x38, 0x9c,
427 0x40, 0x1a,
428 0x41, 0xfe,
429 0x42, 0x33,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700430 0x43, 0x00,
431 0x44, 0xff,
432 0x45, 0x00,
433 0x46, 0x00,
434 0x49, 0x04,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300435 0x4a, 0x51,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700436 0x4b, 0xf8,
437 0x52, 0x30,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300438 0x53, 0x06,
439 0x59, 0x06,
440 0x5a, 0x5e,
441 0x5b, 0x04,
442 0x61, 0x49,
443 0x62, 0x0a,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700444 0x70, 0xff,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300445 0x71, 0x04,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700446 0x72, 0x00,
447 0x73, 0x00,
448 0x74, 0x0c,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300449 0x80, 0x20,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700450 0x81, 0x00,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300451 0x82, 0x30,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700452 0x83, 0x00,
453 0x84, 0x04,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300454 0x85, 0x22,
455 0x86, 0x08,
456 0x87, 0x1b,
457 0x88, 0x00,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700458 0x89, 0x00,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300459 0x90, 0x00,
460 0x91, 0x04,
461 0xa0, 0x86,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700462 0xa1, 0x00,
463 0xa2, 0x00,
464 0xb0, 0x91,
465 0xb1, 0x0b,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300466 0xc0, 0x5b,
467 0xc1, 0x10,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700468 0xc2, 0x12,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300469 0xd0, 0x02,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700470 0xd1, 0x00,
471 0xd2, 0x00,
472 0xd3, 0x00,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300473 0xd4, 0x02,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700474 0xd5, 0x00,
475 0xde, 0x00,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300476 0xdf, 0x01,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700477 0xff, 0xff,
478};
479
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700480static struct stv0297_config alps_tdee4_stv0297_config = {
481 .demod_address = 0x1c,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700482 .inittab = alps_tdee4_stv0297_inittab,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700483// .invert = 1,
484// .pll_set = alps_tdee4_stv0297_pll_set,
485};
486
Patrick Boettcherc9dd82c2008-03-29 21:28:07 -0300487
Patrick Boettcherca19aaa2008-04-13 15:49:22 -0300488/* SkyStar2 rev2.7 (a/u) */
489static struct s5h1420_config skystar2_rev2_7_s5h1420_config = {
490 .demod_address = 0x53,
491 .invert = 1,
492 .repeated_start_workaround = 1,
493};
494
495static struct itd1000_config skystar2_rev2_7_itd1000_config = {
496 .i2c_address = 0x61,
497};
498
499/* SkyStar2 rev2.8 */
Patrick Boettcherc9dd82c2008-03-29 21:28:07 -0300500static struct cx24123_config skystar2_rev2_8_cx24123_config = {
501 .demod_address = 0x55,
502 .dont_use_pll = 1,
503 .agc_callback = cx24113_agc_callback,
504};
505
506static const struct cx24113_config skystar2_rev2_8_cx24113_config = {
507 .i2c_addr = 0x54,
508 .xtal_khz = 10111,
509};
510
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700511/* try to figure out the frontend, each card/box can have on of the following list */
512int flexcop_frontend_init(struct flexcop_device *fc)
513{
Jesper Juhl6a5bdd32006-01-09 15:25:23 -0200514 struct dvb_frontend_ops *ops;
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300515 struct i2c_adapter *i2c = &fc->fc_i2c_adap[0].i2c_adap;
Patrick Boettcherc9dd82c2008-03-29 21:28:07 -0300516 struct i2c_adapter *i2c_tuner;
517
Patrick Boettcherca19aaa2008-04-13 15:49:22 -0300518 /* enable no_base_addr - no repeated start when reading */
519 fc->fc_i2c_adap[0].no_base_addr = 1;
520 fc->fe = dvb_attach(s5h1420_attach, &skystar2_rev2_7_s5h1420_config, i2c);
521 if (fc->fe != NULL) {
522 flexcop_ibi_value r108;
523 i2c_tuner = s5h1420_get_tuner_i2c_adapter(fc->fe);
524 ops = &fc->fe->ops;
525
526 fc->fe_sleep = ops->sleep;
527 ops->sleep = flexcop_sleep;
528
529 fc->dev_type = FC_SKY_REV27;
530
531 /* enable no_base_addr - no repeated start when reading */
532 fc->fc_i2c_adap[2].no_base_addr = 1;
533 if (dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap, 0x08, 1, 1) == NULL)
534 err("ISL6421 could NOT be attached");
535 else
536 info("ISL6421 successfully attached");
537
538 /* the ITD1000 requires a lower i2c clock - it slows down the stuff for everyone - but is it a problem ? */
539 r108.raw = 0x00000506;
540 fc->write_ibi_reg(fc, tw_sm_c_108, r108);
541 if (i2c_tuner) {
542 if (dvb_attach(itd1000_attach, fc->fe, i2c_tuner, &skystar2_rev2_7_itd1000_config) == NULL)
543 err("ITD1000 could NOT be attached");
544 else
545 info("ITD1000 successfully attached");
546 }
547 goto fe_found;
548 }
549 fc->fc_i2c_adap[0].no_base_addr = 0; /* for the next devices we need it again */
550
Patrick Boettcherc9dd82c2008-03-29 21:28:07 -0300551 /* try the sky v2.8 (cx24123, isl6421) */
552 fc->fe = dvb_attach(cx24123_attach,
553 &skystar2_rev2_8_cx24123_config, i2c);
554 if (fc->fe != NULL) {
555 i2c_tuner = cx24123_get_tuner_i2c_adapter(fc->fe);
556 if (i2c_tuner != NULL) {
557 if (dvb_attach(cx24113_attach, fc->fe,
558 &skystar2_rev2_8_cx24113_config,
559 i2c_tuner) == NULL)
560 err("CX24113 could NOT be attached");
561 else
562 info("CX24113 successfully attached");
563 }
564
565 fc->dev_type = FC_SKY_REV28;
566
567 fc->fc_i2c_adap[2].no_base_addr = 1;
568 if (dvb_attach(isl6421_attach, fc->fe,
569 &fc->fc_i2c_adap[2].i2c_adap, 0x08, 0, 0) == NULL)
570 err("ISL6421 could NOT be attached");
571 else
572 info("ISL6421 successfully attached");
573
574 /* TODO on i2c_adap[1] addr 0x11 (EEPROM) there seems to be an
575 * IR-receiver (PIC16F818) - but the card has no input for
576 * that ??? */
577
578 goto fe_found;
579 }
Jesper Juhl6a5bdd32006-01-09 15:25:23 -0200580
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700581 /* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300582 fc->fe = dvb_attach(stv0299_attach, &samsung_tbmu24112_config, i2c);
583 if (fc->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -0300584 ops = &fc->fe->ops;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700585
Andrew de Quincey56e03142006-04-18 17:47:12 -0300586 ops->tuner_ops.set_params = samsung_tbmu24112_tuner_set_params;
587
Jesper Juhl6a5bdd32006-01-09 15:25:23 -0200588 ops->set_voltage = flexcop_set_voltage;
589
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300590 fc->fe_sleep = ops->sleep;
591 ops->sleep = flexcop_sleep;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700592
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300593 fc->dev_type = FC_SKY;
594 goto fe_found;
595 }
596
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700597 /* try the air dvb-t (mt352/Samsung tdtc9251dh0(??)) */
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300598 fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, i2c);
599 if (fc->fe != NULL) {
600 fc->dev_type = FC_AIR_DVB;
Patrick Boettcherdea74862006-05-14 05:01:31 -0300601 fc->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs;
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300602 goto fe_found;
603 }
604
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700605 /* try the air atsc 2nd generation (nxt2002) */
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300606 fc->fe = dvb_attach(nxt200x_attach, &samsung_tbmv_config, i2c);
607 if (fc->fe != NULL) {
608 fc->dev_type = FC_AIR_ATSC2;
Michael Krufky47a99912007-06-12 16:10:51 -0300609 dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL, DVB_PLL_SAMSUNG_TBMV);
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300610 goto fe_found;
611 }
612
613 fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, i2c);
614 if (fc->fe != NULL) {
615 fc->dev_type = FC_AIR_ATSC3;
616 dvb_attach(simple_tuner_attach, fc->fe, i2c, 0x61,
617 TUNER_LG_TDVS_H06XF);
618 goto fe_found;
619 }
620
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700621 /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300622 fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, i2c);
623 if (fc->fe != NULL) {
624 fc->dev_type = FC_AIR_ATSC1;
625 goto fe_found;
626 }
627
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700628 /* try the cable dvb (stv0297) */
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300629 fc->fe = dvb_attach(stv0297_attach, &alps_tdee4_stv0297_config, i2c);
630 if (fc->fe != NULL) {
631 fc->dev_type = FC_CABLE;
Patrick Boettcherdea74862006-05-14 05:01:31 -0300632 fc->fe->ops.tuner_ops.set_params = alps_tdee4_stv0297_tuner_set_params;
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300633 goto fe_found;
634 }
635
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700636 /* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */
Matthias Schwarzotte4671b62008-04-30 12:21:04 -0300637 fc->fe = dvb_attach(mt312_attach,
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300638 &skystar23_samsung_tbdu18132_config, i2c);
639 if (fc->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -0300640 ops = &fc->fe->ops;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700641
Andrew de Quincey56e03142006-04-18 17:47:12 -0300642 ops->tuner_ops.set_params = skystar23_samsung_tbdu18132_tuner_set_params;
643
Jesper Juhl6a5bdd32006-01-09 15:25:23 -0200644 ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
645 ops->diseqc_send_burst = flexcop_diseqc_send_burst;
646 ops->set_tone = flexcop_set_tone;
647 ops->set_voltage = flexcop_set_voltage;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700648
Jesper Juhl6a5bdd32006-01-09 15:25:23 -0200649 fc->fe_sleep = ops->sleep;
650 ops->sleep = flexcop_sleep;
651
652 fc->dev_type = FC_SKY_OLD;
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300653 goto fe_found;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700654 }
655
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300656 err("no frontend driver found for this B2C2/FlexCop adapter");
657 return -ENODEV;
658
659fe_found:
660 info("found '%s' .", fc->fe->ops.info.name);
661 if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) {
662 err("frontend registration failed!");
663 ops = &fc->fe->ops;
664 if (ops->release != NULL)
665 ops->release(fc->fe);
666 fc->fe = NULL;
667 return -EINVAL;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700668 }
669 fc->init_state |= FC_STATE_FE_INIT;
670 return 0;
671}
672
673void flexcop_frontend_exit(struct flexcop_device *fc)
674{
Andrew de Quincey2bfe0312006-08-08 09:10:08 -0300675 if (fc->init_state & FC_STATE_FE_INIT) {
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700676 dvb_unregister_frontend(fc->fe);
Andrew de Quinceyf52a8382006-08-08 09:10:09 -0300677 dvb_frontend_detach(fc->fe);
Andrew de Quincey2bfe0312006-08-08 09:10:08 -0300678 }
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700679
680 fc->init_state &= ~FC_STATE_FE_INIT;
681}