blob: a127a4175c402a45c1940d7dec586762557544b5 [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);
Thierry MERLEc4e3fd92008-09-01 17:32:10 -0300140 mdelay(12);
141 udelay(500);
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700142 flexcop_set_tone(fe, SEC_TONE_OFF);
143 }
144 msleep(20);
145 }
146 return 0;
147}
148
149static int flexcop_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
150{
151 return flexcop_send_diseqc_msg(fe, cmd->msg_len, cmd->msg, 0);
152}
153
154static int flexcop_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
155{
156 return flexcop_send_diseqc_msg(fe, 0, NULL, minicmd);
157}
158
159/* dvb-s stv0299 */
160static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
161{
162 u8 aclk = 0;
163 u8 bclk = 0;
164
165 if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
166 else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
167 else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
168 else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
169 else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
170 else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
171
172 stv0299_writereg (fe, 0x13, aclk);
173 stv0299_writereg (fe, 0x14, bclk);
174 stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff);
175 stv0299_writereg (fe, 0x20, (ratio >> 8) & 0xff);
176 stv0299_writereg (fe, 0x21, (ratio ) & 0xf0);
177
178 return 0;
179}
180
Andrew de Quincey56e03142006-04-18 17:47:12 -0300181static int samsung_tbmu24112_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params)
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700182{
183 u8 buf[4];
184 u32 div;
185 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
Andrew de Quincey56e03142006-04-18 17:47:12 -0300186 struct flexcop_device *fc = fe->dvb->priv;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700187
188 div = params->frequency / 125;
189
190 buf[0] = (div >> 8) & 0x7f;
191 buf[1] = div & 0xff;
192 buf[2] = 0x84; /* 0xC4 */
193 buf[3] = 0x08;
194
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300195 if (params->frequency < 1500000)
196 buf[3] |= 0x10;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700197
Patrick Boettcherdea74862006-05-14 05:01:31 -0300198 if (fe->ops.i2c_gate_ctrl)
199 fe->ops.i2c_gate_ctrl(fe, 1);
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300200 if (i2c_transfer(&fc->fc_i2c_adap[0].i2c_adap, &msg, 1) != 1)
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700201 return -EIO;
202 return 0;
203}
204
205static u8 samsung_tbmu24112_inittab[] = {
206 0x01, 0x15,
207 0x02, 0x30,
208 0x03, 0x00,
209 0x04, 0x7D,
210 0x05, 0x35,
211 0x06, 0x02,
212 0x07, 0x00,
213 0x08, 0xC3,
214 0x0C, 0x00,
215 0x0D, 0x81,
216 0x0E, 0x23,
217 0x0F, 0x12,
218 0x10, 0x7E,
219 0x11, 0x84,
220 0x12, 0xB9,
221 0x13, 0x88,
222 0x14, 0x89,
223 0x15, 0xC9,
224 0x16, 0x00,
225 0x17, 0x5C,
226 0x18, 0x00,
227 0x19, 0x00,
228 0x1A, 0x00,
229 0x1C, 0x00,
230 0x1D, 0x00,
231 0x1E, 0x00,
232 0x1F, 0x3A,
233 0x20, 0x2E,
234 0x21, 0x80,
235 0x22, 0xFF,
236 0x23, 0xC1,
237 0x28, 0x00,
238 0x29, 0x1E,
239 0x2A, 0x14,
240 0x2B, 0x0F,
241 0x2C, 0x09,
242 0x2D, 0x05,
243 0x31, 0x1F,
244 0x32, 0x19,
245 0x33, 0xFE,
246 0x34, 0x93,
247 0xff, 0xff,
248};
249
250static struct stv0299_config samsung_tbmu24112_config = {
251 .demod_address = 0x68,
252 .inittab = samsung_tbmu24112_inittab,
253 .mclk = 88000000UL,
254 .invert = 0,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700255 .skip_reinit = 0,
Oliver Endrissda2c7f62008-04-20 22:13:37 -0300256 .lock_output = STV0299_LOCKOUTPUT_LK,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700257 .volt13_op0_op1 = STV0299_VOLT13_OP1,
258 .min_delay_ms = 100,
259 .set_symbol_rate = samsung_tbmu24112_set_symbol_rate,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700260};
261
262/* dvb-t mt352 */
263static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
264{
265 static u8 mt352_clock_config [] = { 0x89, 0x18, 0x2d };
266 static u8 mt352_reset [] = { 0x50, 0x80 };
267 static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
268 static u8 mt352_agc_cfg [] = { 0x67, 0x28, 0xa1 };
269 static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
270
271 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
272 udelay(2000);
273 mt352_write(fe, mt352_reset, sizeof(mt352_reset));
274 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
275
276 mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
277 mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
278
279 return 0;
280}
281
Andrew de Quincey56e03142006-04-18 17:47:12 -0300282static 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 -0700283{
284 u32 div;
285 unsigned char bs = 0;
286
Andrew de Quincey56e03142006-04-18 17:47:12 -0300287 if (buf_len < 5)
288 return -EINVAL;
289
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700290 #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
291 div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
292
293 if (params->frequency >= 48000000 && params->frequency <= 154000000) bs = 0x09;
294 if (params->frequency >= 161000000 && params->frequency <= 439000000) bs = 0x0a;
295 if (params->frequency >= 447000000 && params->frequency <= 863000000) bs = 0x08;
296
Andrew de Quincey56e03142006-04-18 17:47:12 -0300297 pllbuf[0] = 0x61;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700298 pllbuf[1] = div >> 8;
299 pllbuf[2] = div & 0xff;
300 pllbuf[3] = 0xcc;
301 pllbuf[4] = bs;
302
Andrew de Quincey56e03142006-04-18 17:47:12 -0300303 return 5;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700304}
305
306static struct mt352_config samsung_tdtc9251dh0_config = {
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700307 .demod_address = 0x0f,
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700308 .demod_init = samsung_tdtc9251dh0_demod_init,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700309};
310
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700311static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700312{
313 struct flexcop_device *fc = fe->dvb->priv;
314 return request_firmware(fw, name, fc->dev);
315}
316
Michael Krufkyc0b11b92005-11-08 21:35:32 -0800317static struct lgdt330x_config air2pc_atsc_hd5000_config = {
318 .demod_address = 0x59,
319 .demod_chip = LGDT3303,
320 .serial_mpeg = 0x04,
Michael Krufkyc0b11b92005-11-08 21:35:32 -0800321 .clock_polarity_flip = 1,
322};
323
Michael Krufky46365f32006-01-23 09:52:39 -0200324static struct nxt200x_config samsung_tbmv_config = {
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700325 .demod_address = 0x0a,
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700326};
327
328static struct bcm3510_config air2pc_atsc_first_gen_config = {
329 .demod_address = 0x0f,
330 .request_firmware = flexcop_fe_request_firmware,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700331};
332
Andrew de Quincey56e03142006-04-18 17:47:12 -0300333static int skystar23_samsung_tbdu18132_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params)
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700334{
335 u8 buf[4];
336 u32 div;
337 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
338 struct flexcop_device *fc = fe->dvb->priv;
339
340 div = (params->frequency + (125/2)) / 125;
341
342 buf[0] = (div >> 8) & 0x7f;
343 buf[1] = (div >> 0) & 0xff;
344 buf[2] = 0x84 | ((div >> 10) & 0x60);
345 buf[3] = 0x80;
346
347 if (params->frequency < 1550000)
348 buf[3] |= 0x02;
349
Patrick Boettcherdea74862006-05-14 05:01:31 -0300350 if (fe->ops.i2c_gate_ctrl)
351 fe->ops.i2c_gate_ctrl(fe, 1);
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300352 if (i2c_transfer(&fc->fc_i2c_adap[0].i2c_adap, &msg, 1) != 1)
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700353 return -EIO;
354 return 0;
355}
356
357static struct mt312_config skystar23_samsung_tbdu18132_config = {
358
359 .demod_address = 0x0e,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700360};
361
Adrian Bunkdd00b1e2006-05-29 12:31:44 -0300362static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe,
363 struct dvb_frontend_parameters *fep)
Andrew de Quincey56e03142006-04-18 17:47:12 -0300364{
365 struct flexcop_device *fc = fe->dvb->priv;
366 u8 buf[4];
367 u16 div;
368 int ret;
369
370/* 62.5 kHz * 10 */
371#define REF_FREQ 625
372#define FREQ_OFFSET 36125
373
374 div = ((fep->frequency/1000 + FREQ_OFFSET ) * 10) / REF_FREQ; // 4 MHz = 4000 KHz
375
376 buf[0] = (u8)( div >> 8) & 0x7f;
377 buf[1] = (u8) div & 0xff;
378
379/* F(osc) = N * Reference Freq. (62.5 kHz)
380 * byte 2 : 0 N14 N13 N12 N11 N10 N9 N8
381 * byte 3 : N7 N6 N5 N4 N3 N2 N1 N0
382 * byte 4 : 1 * * AGD R3 R2 R1 R0
383 * byte 5 : C1 * RE RTS BS4 BS3 BS2 BS1
384 * AGD = 1, R3 R2 R1 R0 = 0 1 0 1 => byte 4 = 1**10101 = 0x95 */
385 buf[2] = 0x95;
386
387// Range(MHz) C1 * RE RTS BS4 BS3 BS2 BS1 Byte 5
388// 47 - 153 0 * 0 0 0 0 0 1 0x01
389// 153 - 430 0 * 0 0 0 0 1 0 0x02
390// 430 - 822 0 * 0 0 1 0 0 0 0x08
391// 822 - 862 1 * 0 0 1 0 0 0 0x88
392
393 if (fep->frequency <= 153000000) buf[3] = 0x01;
394 else if (fep->frequency <= 430000000) buf[3] = 0x02;
395 else if (fep->frequency <= 822000000) buf[3] = 0x08;
396 else buf[3] = 0x88;
397
Patrick Boettcherdea74862006-05-14 05:01:31 -0300398 if (fe->ops.i2c_gate_ctrl)
Antti Seppälä9d85d772006-12-20 11:10:35 -0300399 fe->ops.i2c_gate_ctrl(fe, 0);
Andrew de Quincey56e03142006-04-18 17:47:12 -0300400 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 -0300401 ret = fc->i2c_request(&fc->fc_i2c_adap[2],
402 FC_WRITE, 0x61, buf[0], &buf[1], 3);
Andrew de Quincey56e03142006-04-18 17:47:12 -0300403 deb_tuner("tuner write returned: %d\n",ret);
404
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300405 return ret;
Andrew de Quincey56e03142006-04-18 17:47:12 -0300406}
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700407
408static u8 alps_tdee4_stv0297_inittab[] = {
409 0x80, 0x01,
410 0x80, 0x00,
411 0x81, 0x01,
412 0x81, 0x00,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300413 0x00, 0x48,
414 0x01, 0x58,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700415 0x03, 0x00,
416 0x04, 0x00,
417 0x07, 0x00,
418 0x08, 0x00,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700419 0x30, 0xff,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300420 0x31, 0x9d,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700421 0x32, 0xff,
422 0x33, 0x00,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300423 0x34, 0x29,
424 0x35, 0x55,
425 0x36, 0x80,
426 0x37, 0x6e,
427 0x38, 0x9c,
428 0x40, 0x1a,
429 0x41, 0xfe,
430 0x42, 0x33,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700431 0x43, 0x00,
432 0x44, 0xff,
433 0x45, 0x00,
434 0x46, 0x00,
435 0x49, 0x04,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300436 0x4a, 0x51,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700437 0x4b, 0xf8,
438 0x52, 0x30,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300439 0x53, 0x06,
440 0x59, 0x06,
441 0x5a, 0x5e,
442 0x5b, 0x04,
443 0x61, 0x49,
444 0x62, 0x0a,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700445 0x70, 0xff,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300446 0x71, 0x04,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700447 0x72, 0x00,
448 0x73, 0x00,
449 0x74, 0x0c,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300450 0x80, 0x20,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700451 0x81, 0x00,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300452 0x82, 0x30,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700453 0x83, 0x00,
454 0x84, 0x04,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300455 0x85, 0x22,
456 0x86, 0x08,
457 0x87, 0x1b,
458 0x88, 0x00,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700459 0x89, 0x00,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300460 0x90, 0x00,
461 0x91, 0x04,
462 0xa0, 0x86,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700463 0xa1, 0x00,
464 0xa2, 0x00,
465 0xb0, 0x91,
466 0xb1, 0x0b,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300467 0xc0, 0x5b,
468 0xc1, 0x10,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700469 0xc2, 0x12,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300470 0xd0, 0x02,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700471 0xd1, 0x00,
472 0xd2, 0x00,
473 0xd3, 0x00,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300474 0xd4, 0x02,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700475 0xd5, 0x00,
476 0xde, 0x00,
Antti Seppälä9d85d772006-12-20 11:10:35 -0300477 0xdf, 0x01,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700478 0xff, 0xff,
479};
480
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700481static struct stv0297_config alps_tdee4_stv0297_config = {
482 .demod_address = 0x1c,
Andrew de Quinceydc27a162005-09-09 13:03:07 -0700483 .inittab = alps_tdee4_stv0297_inittab,
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700484// .invert = 1,
485// .pll_set = alps_tdee4_stv0297_pll_set,
486};
487
Patrick Boettcherc9dd82c2008-03-29 21:28:07 -0300488
Patrick Boettcherca19aaa2008-04-13 15:49:22 -0300489/* SkyStar2 rev2.7 (a/u) */
490static struct s5h1420_config skystar2_rev2_7_s5h1420_config = {
491 .demod_address = 0x53,
492 .invert = 1,
493 .repeated_start_workaround = 1,
Patrick Boettcherc18c5ff2008-09-06 13:31:58 -0300494 .serial_mpeg = 1,
Patrick Boettcherca19aaa2008-04-13 15:49:22 -0300495};
496
497static struct itd1000_config skystar2_rev2_7_itd1000_config = {
498 .i2c_address = 0x61,
499};
500
501/* SkyStar2 rev2.8 */
Patrick Boettcherc9dd82c2008-03-29 21:28:07 -0300502static struct cx24123_config skystar2_rev2_8_cx24123_config = {
503 .demod_address = 0x55,
504 .dont_use_pll = 1,
505 .agc_callback = cx24113_agc_callback,
506};
507
508static const struct cx24113_config skystar2_rev2_8_cx24113_config = {
509 .i2c_addr = 0x54,
510 .xtal_khz = 10111,
511};
512
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700513/* try to figure out the frontend, each card/box can have on of the following list */
514int flexcop_frontend_init(struct flexcop_device *fc)
515{
Jesper Juhl6a5bdd32006-01-09 15:25:23 -0200516 struct dvb_frontend_ops *ops;
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300517 struct i2c_adapter *i2c = &fc->fc_i2c_adap[0].i2c_adap;
Patrick Boettcherc9dd82c2008-03-29 21:28:07 -0300518 struct i2c_adapter *i2c_tuner;
519
Patrick Boettcherca19aaa2008-04-13 15:49:22 -0300520 /* enable no_base_addr - no repeated start when reading */
521 fc->fc_i2c_adap[0].no_base_addr = 1;
522 fc->fe = dvb_attach(s5h1420_attach, &skystar2_rev2_7_s5h1420_config, i2c);
523 if (fc->fe != NULL) {
524 flexcop_ibi_value r108;
525 i2c_tuner = s5h1420_get_tuner_i2c_adapter(fc->fe);
526 ops = &fc->fe->ops;
527
528 fc->fe_sleep = ops->sleep;
529 ops->sleep = flexcop_sleep;
530
531 fc->dev_type = FC_SKY_REV27;
532
533 /* enable no_base_addr - no repeated start when reading */
534 fc->fc_i2c_adap[2].no_base_addr = 1;
535 if (dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap, 0x08, 1, 1) == NULL)
536 err("ISL6421 could NOT be attached");
537 else
538 info("ISL6421 successfully attached");
539
540 /* the ITD1000 requires a lower i2c clock - it slows down the stuff for everyone - but is it a problem ? */
541 r108.raw = 0x00000506;
542 fc->write_ibi_reg(fc, tw_sm_c_108, r108);
543 if (i2c_tuner) {
544 if (dvb_attach(itd1000_attach, fc->fe, i2c_tuner, &skystar2_rev2_7_itd1000_config) == NULL)
545 err("ITD1000 could NOT be attached");
546 else
547 info("ITD1000 successfully attached");
548 }
549 goto fe_found;
550 }
551 fc->fc_i2c_adap[0].no_base_addr = 0; /* for the next devices we need it again */
552
Patrick Boettcherc9dd82c2008-03-29 21:28:07 -0300553 /* try the sky v2.8 (cx24123, isl6421) */
554 fc->fe = dvb_attach(cx24123_attach,
555 &skystar2_rev2_8_cx24123_config, i2c);
556 if (fc->fe != NULL) {
557 i2c_tuner = cx24123_get_tuner_i2c_adapter(fc->fe);
558 if (i2c_tuner != NULL) {
559 if (dvb_attach(cx24113_attach, fc->fe,
560 &skystar2_rev2_8_cx24113_config,
561 i2c_tuner) == NULL)
562 err("CX24113 could NOT be attached");
563 else
564 info("CX24113 successfully attached");
565 }
566
567 fc->dev_type = FC_SKY_REV28;
568
569 fc->fc_i2c_adap[2].no_base_addr = 1;
570 if (dvb_attach(isl6421_attach, fc->fe,
571 &fc->fc_i2c_adap[2].i2c_adap, 0x08, 0, 0) == NULL)
572 err("ISL6421 could NOT be attached");
573 else
574 info("ISL6421 successfully attached");
575
576 /* TODO on i2c_adap[1] addr 0x11 (EEPROM) there seems to be an
577 * IR-receiver (PIC16F818) - but the card has no input for
578 * that ??? */
579
580 goto fe_found;
581 }
Jesper Juhl6a5bdd32006-01-09 15:25:23 -0200582
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700583 /* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300584 fc->fe = dvb_attach(stv0299_attach, &samsung_tbmu24112_config, i2c);
585 if (fc->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -0300586 ops = &fc->fe->ops;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700587
Andrew de Quincey56e03142006-04-18 17:47:12 -0300588 ops->tuner_ops.set_params = samsung_tbmu24112_tuner_set_params;
589
Jesper Juhl6a5bdd32006-01-09 15:25:23 -0200590 ops->set_voltage = flexcop_set_voltage;
591
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300592 fc->fe_sleep = ops->sleep;
593 ops->sleep = flexcop_sleep;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700594
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300595 fc->dev_type = FC_SKY;
596 goto fe_found;
597 }
598
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700599 /* try the air dvb-t (mt352/Samsung tdtc9251dh0(??)) */
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300600 fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, i2c);
601 if (fc->fe != NULL) {
602 fc->dev_type = FC_AIR_DVB;
Patrick Boettcherdea74862006-05-14 05:01:31 -0300603 fc->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs;
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300604 goto fe_found;
605 }
606
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700607 /* try the air atsc 2nd generation (nxt2002) */
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300608 fc->fe = dvb_attach(nxt200x_attach, &samsung_tbmv_config, i2c);
609 if (fc->fe != NULL) {
610 fc->dev_type = FC_AIR_ATSC2;
Michael Krufky47a99912007-06-12 16:10:51 -0300611 dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL, DVB_PLL_SAMSUNG_TBMV);
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300612 goto fe_found;
613 }
614
615 fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, i2c);
616 if (fc->fe != NULL) {
617 fc->dev_type = FC_AIR_ATSC3;
618 dvb_attach(simple_tuner_attach, fc->fe, i2c, 0x61,
619 TUNER_LG_TDVS_H06XF);
620 goto fe_found;
621 }
622
Johannes Stezenbach55f51ef2005-06-23 22:02:41 -0700623 /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300624 fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, i2c);
625 if (fc->fe != NULL) {
626 fc->dev_type = FC_AIR_ATSC1;
627 goto fe_found;
628 }
629
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700630 /* try the cable dvb (stv0297) */
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300631 fc->fe = dvb_attach(stv0297_attach, &alps_tdee4_stv0297_config, i2c);
632 if (fc->fe != NULL) {
633 fc->dev_type = FC_CABLE;
Patrick Boettcherdea74862006-05-14 05:01:31 -0300634 fc->fe->ops.tuner_ops.set_params = alps_tdee4_stv0297_tuner_set_params;
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300635 goto fe_found;
636 }
637
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700638 /* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */
Matthias Schwarzotte4671b62008-04-30 12:21:04 -0300639 fc->fe = dvb_attach(mt312_attach,
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300640 &skystar23_samsung_tbdu18132_config, i2c);
641 if (fc->fe != NULL) {
Patrick Boettcherdea74862006-05-14 05:01:31 -0300642 ops = &fc->fe->ops;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700643
Andrew de Quincey56e03142006-04-18 17:47:12 -0300644 ops->tuner_ops.set_params = skystar23_samsung_tbdu18132_tuner_set_params;
645
Jesper Juhl6a5bdd32006-01-09 15:25:23 -0200646 ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
647 ops->diseqc_send_burst = flexcop_diseqc_send_burst;
648 ops->set_tone = flexcop_set_tone;
649 ops->set_voltage = flexcop_set_voltage;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700650
Jesper Juhl6a5bdd32006-01-09 15:25:23 -0200651 fc->fe_sleep = ops->sleep;
652 ops->sleep = flexcop_sleep;
653
654 fc->dev_type = FC_SKY_OLD;
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300655 goto fe_found;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700656 }
657
Patrick Boettcher6394cf52008-03-29 20:49:57 -0300658 err("no frontend driver found for this B2C2/FlexCop adapter");
659 return -ENODEV;
660
661fe_found:
662 info("found '%s' .", fc->fe->ops.info.name);
663 if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) {
664 err("frontend registration failed!");
665 ops = &fc->fe->ops;
666 if (ops->release != NULL)
667 ops->release(fc->fe);
668 fc->fe = NULL;
669 return -EINVAL;
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700670 }
671 fc->init_state |= FC_STATE_FE_INIT;
672 return 0;
673}
674
675void flexcop_frontend_exit(struct flexcop_device *fc)
676{
Andrew de Quincey2bfe0312006-08-08 09:10:08 -0300677 if (fc->init_state & FC_STATE_FE_INIT) {
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700678 dvb_unregister_frontend(fc->fe);
Andrew de Quinceyf52a8382006-08-08 09:10:09 -0300679 dvb_frontend_detach(fc->fe);
Andrew de Quincey2bfe0312006-08-08 09:10:08 -0300680 }
Johannes Stezenbach2add87a2005-05-16 21:54:10 -0700681
682 fc->init_state &= ~FC_STATE_FE_INIT;
683}