diff options
Diffstat (limited to 'drivers/media/dvb')
115 files changed, 3766 insertions, 1543 deletions
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c index 9c7f122826e0..3be87c72e37b 100644 --- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c +++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include "stv0297.h" | 14 | #include "stv0297.h" |
15 | #include "mt312.h" | 15 | #include "mt312.h" |
16 | #include "lgdt330x.h" | 16 | #include "lgdt330x.h" |
17 | #include "lg_h06xf.h" | ||
17 | #include "dvb-pll.h" | 18 | #include "dvb-pll.h" |
18 | 19 | ||
19 | /* lnb control */ | 20 | /* lnb control */ |
@@ -166,11 +167,12 @@ static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend* fe, u32 srate, | |||
166 | return 0; | 167 | return 0; |
167 | } | 168 | } |
168 | 169 | ||
169 | static int samsung_tbmu24112_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params) | 170 | static int samsung_tbmu24112_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) |
170 | { | 171 | { |
171 | u8 buf[4]; | 172 | u8 buf[4]; |
172 | u32 div; | 173 | u32 div; |
173 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; | 174 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; |
175 | struct flexcop_device *fc = fe->dvb->priv; | ||
174 | 176 | ||
175 | div = params->frequency / 125; | 177 | div = params->frequency / 125; |
176 | 178 | ||
@@ -181,8 +183,11 @@ static int samsung_tbmu24112_pll_set(struct dvb_frontend* fe, struct i2c_adapter | |||
181 | 183 | ||
182 | if (params->frequency < 1500000) buf[3] |= 0x10; | 184 | if (params->frequency < 1500000) buf[3] |= 0x10; |
183 | 185 | ||
184 | if (i2c_transfer(i2c, &msg, 1) != 1) | 186 | if (fe->ops.i2c_gate_ctrl) |
187 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
188 | if (i2c_transfer(&fc->i2c_adap, &msg, 1) != 1) { | ||
185 | return -EIO; | 189 | return -EIO; |
190 | } | ||
186 | return 0; | 191 | return 0; |
187 | } | 192 | } |
188 | 193 | ||
@@ -241,7 +246,6 @@ static struct stv0299_config samsung_tbmu24112_config = { | |||
241 | .volt13_op0_op1 = STV0299_VOLT13_OP1, | 246 | .volt13_op0_op1 = STV0299_VOLT13_OP1, |
242 | .min_delay_ms = 100, | 247 | .min_delay_ms = 100, |
243 | .set_symbol_rate = samsung_tbmu24112_set_symbol_rate, | 248 | .set_symbol_rate = samsung_tbmu24112_set_symbol_rate, |
244 | .pll_set = samsung_tbmu24112_pll_set, | ||
245 | }; | 249 | }; |
246 | 250 | ||
247 | /* dvb-t mt352 */ | 251 | /* dvb-t mt352 */ |
@@ -264,11 +268,14 @@ static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe) | |||
264 | return 0; | 268 | return 0; |
265 | } | 269 | } |
266 | 270 | ||
267 | static int samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf) | 271 | static int samsung_tdtc9251dh0_calc_regs(struct dvb_frontend* fe, struct dvb_frontend_parameters *params, u8* pllbuf, int buf_len) |
268 | { | 272 | { |
269 | u32 div; | 273 | u32 div; |
270 | unsigned char bs = 0; | 274 | unsigned char bs = 0; |
271 | 275 | ||
276 | if (buf_len < 5) | ||
277 | return -EINVAL; | ||
278 | |||
272 | #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */ | 279 | #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */ |
273 | div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; | 280 | div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; |
274 | 281 | ||
@@ -276,19 +283,18 @@ static int samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct dvb_front | |||
276 | if (params->frequency >= 161000000 && params->frequency <= 439000000) bs = 0x0a; | 283 | if (params->frequency >= 161000000 && params->frequency <= 439000000) bs = 0x0a; |
277 | if (params->frequency >= 447000000 && params->frequency <= 863000000) bs = 0x08; | 284 | if (params->frequency >= 447000000 && params->frequency <= 863000000) bs = 0x08; |
278 | 285 | ||
279 | pllbuf[0] = 0xc2; /* Note: non-linux standard PLL i2c address */ | 286 | pllbuf[0] = 0x61; |
280 | pllbuf[1] = div >> 8; | 287 | pllbuf[1] = div >> 8; |
281 | pllbuf[2] = div & 0xff; | 288 | pllbuf[2] = div & 0xff; |
282 | pllbuf[3] = 0xcc; | 289 | pllbuf[3] = 0xcc; |
283 | pllbuf[4] = bs; | 290 | pllbuf[4] = bs; |
284 | 291 | ||
285 | return 0; | 292 | return 5; |
286 | } | 293 | } |
287 | 294 | ||
288 | static struct mt352_config samsung_tdtc9251dh0_config = { | 295 | static struct mt352_config samsung_tdtc9251dh0_config = { |
289 | .demod_address = 0x0f, | 296 | .demod_address = 0x0f, |
290 | .demod_init = samsung_tdtc9251dh0_demod_init, | 297 | .demod_init = samsung_tdtc9251dh0_demod_init, |
291 | .pll_set = samsung_tdtc9251dh0_pll_set, | ||
292 | }; | 298 | }; |
293 | 299 | ||
294 | static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name) | 300 | static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name) |
@@ -297,56 +303,21 @@ static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct fir | |||
297 | return request_firmware(fw, name, fc->dev); | 303 | return request_firmware(fw, name, fc->dev); |
298 | } | 304 | } |
299 | 305 | ||
300 | static int lgdt3303_pll_set(struct dvb_frontend* fe, | 306 | static int lgdt3303_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) |
301 | struct dvb_frontend_parameters* params) | ||
302 | { | 307 | { |
303 | struct flexcop_device *fc = fe->dvb->priv; | 308 | struct flexcop_device *fc = fe->dvb->priv; |
304 | u8 buf[4]; | 309 | return lg_h06xf_pll_set(fe, &fc->i2c_adap, params); |
305 | struct i2c_msg msg = | ||
306 | { .addr = 0x61, .flags = 0, .buf = buf, .len = 4 }; | ||
307 | int err; | ||
308 | |||
309 | dvb_pll_configure(&dvb_pll_tdvs_tua6034,buf, params->frequency, 0); | ||
310 | dprintk(1, "%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n", | ||
311 | __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]); | ||
312 | if ((err = i2c_transfer(&fc->i2c_adap, &msg, 1)) != 1) { | ||
313 | printk(KERN_WARNING "lgdt3303: %s error " | ||
314 | "(addr %02x <- %02x, err = %i)\n", | ||
315 | __FUNCTION__, buf[0], buf[1], err); | ||
316 | if (err < 0) | ||
317 | return err; | ||
318 | else | ||
319 | return -EREMOTEIO; | ||
320 | } | ||
321 | |||
322 | buf[0] = 0x86 | 0x18; | ||
323 | buf[1] = 0x50; | ||
324 | msg.len = 2; | ||
325 | if ((err = i2c_transfer(&fc->i2c_adap, &msg, 1)) != 1) { | ||
326 | printk(KERN_WARNING "lgdt3303: %s error " | ||
327 | "(addr %02x <- %02x, err = %i)\n", | ||
328 | __FUNCTION__, buf[0], buf[1], err); | ||
329 | if (err < 0) | ||
330 | return err; | ||
331 | else | ||
332 | return -EREMOTEIO; | ||
333 | } | ||
334 | |||
335 | return 0; | ||
336 | } | 310 | } |
337 | 311 | ||
338 | static struct lgdt330x_config air2pc_atsc_hd5000_config = { | 312 | static struct lgdt330x_config air2pc_atsc_hd5000_config = { |
339 | .demod_address = 0x59, | 313 | .demod_address = 0x59, |
340 | .demod_chip = LGDT3303, | 314 | .demod_chip = LGDT3303, |
341 | .serial_mpeg = 0x04, | 315 | .serial_mpeg = 0x04, |
342 | .pll_set = lgdt3303_pll_set, | ||
343 | .clock_polarity_flip = 1, | 316 | .clock_polarity_flip = 1, |
344 | }; | 317 | }; |
345 | 318 | ||
346 | static struct nxt200x_config samsung_tbmv_config = { | 319 | static struct nxt200x_config samsung_tbmv_config = { |
347 | .demod_address = 0x0a, | 320 | .demod_address = 0x0a, |
348 | .pll_address = 0xc2, | ||
349 | .pll_desc = &dvb_pll_samsung_tbmv, | ||
350 | }; | 321 | }; |
351 | 322 | ||
352 | static struct bcm3510_config air2pc_atsc_first_gen_config = { | 323 | static struct bcm3510_config air2pc_atsc_first_gen_config = { |
@@ -354,7 +325,7 @@ static struct bcm3510_config air2pc_atsc_first_gen_config = { | |||
354 | .request_firmware = flexcop_fe_request_firmware, | 325 | .request_firmware = flexcop_fe_request_firmware, |
355 | }; | 326 | }; |
356 | 327 | ||
357 | static int skystar23_samsung_tbdu18132_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 328 | static int skystar23_samsung_tbdu18132_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) |
358 | { | 329 | { |
359 | u8 buf[4]; | 330 | u8 buf[4]; |
360 | u32 div; | 331 | u32 div; |
@@ -371,6 +342,8 @@ static int skystar23_samsung_tbdu18132_pll_set(struct dvb_frontend* fe, struct d | |||
371 | if (params->frequency < 1550000) | 342 | if (params->frequency < 1550000) |
372 | buf[3] |= 0x02; | 343 | buf[3] |= 0x02; |
373 | 344 | ||
345 | if (fe->ops.i2c_gate_ctrl) | ||
346 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
374 | if (i2c_transfer(&fc->i2c_adap, &msg, 1) != 1) | 347 | if (i2c_transfer(&fc->i2c_adap, &msg, 1) != 1) |
375 | return -EIO; | 348 | return -EIO; |
376 | return 0; | 349 | return 0; |
@@ -379,9 +352,52 @@ static int skystar23_samsung_tbdu18132_pll_set(struct dvb_frontend* fe, struct d | |||
379 | static struct mt312_config skystar23_samsung_tbdu18132_config = { | 352 | static struct mt312_config skystar23_samsung_tbdu18132_config = { |
380 | 353 | ||
381 | .demod_address = 0x0e, | 354 | .demod_address = 0x0e, |
382 | .pll_set = skystar23_samsung_tbdu18132_pll_set, | ||
383 | }; | 355 | }; |
384 | 356 | ||
357 | static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe, | ||
358 | struct dvb_frontend_parameters *fep) | ||
359 | { | ||
360 | struct flexcop_device *fc = fe->dvb->priv; | ||
361 | u8 buf[4]; | ||
362 | u16 div; | ||
363 | int ret; | ||
364 | |||
365 | /* 62.5 kHz * 10 */ | ||
366 | #define REF_FREQ 625 | ||
367 | #define FREQ_OFFSET 36125 | ||
368 | |||
369 | div = ((fep->frequency/1000 + FREQ_OFFSET ) * 10) / REF_FREQ; // 4 MHz = 4000 KHz | ||
370 | |||
371 | buf[0] = (u8)( div >> 8) & 0x7f; | ||
372 | buf[1] = (u8) div & 0xff; | ||
373 | |||
374 | /* F(osc) = N * Reference Freq. (62.5 kHz) | ||
375 | * byte 2 : 0 N14 N13 N12 N11 N10 N9 N8 | ||
376 | * byte 3 : N7 N6 N5 N4 N3 N2 N1 N0 | ||
377 | * byte 4 : 1 * * AGD R3 R2 R1 R0 | ||
378 | * byte 5 : C1 * RE RTS BS4 BS3 BS2 BS1 | ||
379 | * AGD = 1, R3 R2 R1 R0 = 0 1 0 1 => byte 4 = 1**10101 = 0x95 */ | ||
380 | buf[2] = 0x95; | ||
381 | |||
382 | // Range(MHz) C1 * RE RTS BS4 BS3 BS2 BS1 Byte 5 | ||
383 | // 47 - 153 0 * 0 0 0 0 0 1 0x01 | ||
384 | // 153 - 430 0 * 0 0 0 0 1 0 0x02 | ||
385 | // 430 - 822 0 * 0 0 1 0 0 0 0x08 | ||
386 | // 822 - 862 1 * 0 0 1 0 0 0 0x88 | ||
387 | |||
388 | if (fep->frequency <= 153000000) buf[3] = 0x01; | ||
389 | else if (fep->frequency <= 430000000) buf[3] = 0x02; | ||
390 | else if (fep->frequency <= 822000000) buf[3] = 0x08; | ||
391 | else buf[3] = 0x88; | ||
392 | |||
393 | if (fe->ops.i2c_gate_ctrl) | ||
394 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
395 | deb_tuner("tuner buffer for %d Hz: %x %x %x %x\n",fep->frequency, buf[0],buf[1],buf[2],buf[3]); | ||
396 | ret = fc->i2c_request(fc,FC_WRITE,FC_I2C_PORT_TUNER,0x61,buf[0],&buf[1],3); | ||
397 | deb_tuner("tuner write returned: %d\n",ret); | ||
398 | |||
399 | return 0; | ||
400 | } | ||
385 | 401 | ||
386 | static u8 alps_tdee4_stv0297_inittab[] = { | 402 | static u8 alps_tdee4_stv0297_inittab[] = { |
387 | 0x80, 0x01, | 403 | 0x80, 0x01, |
@@ -490,7 +506,9 @@ int flexcop_frontend_init(struct flexcop_device *fc) | |||
490 | 506 | ||
491 | /* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */ | 507 | /* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */ |
492 | if ((fc->fe = stv0299_attach(&samsung_tbmu24112_config, &fc->i2c_adap)) != NULL) { | 508 | if ((fc->fe = stv0299_attach(&samsung_tbmu24112_config, &fc->i2c_adap)) != NULL) { |
493 | ops = fc->fe->ops; | 509 | ops = &fc->fe->ops; |
510 | |||
511 | ops->tuner_ops.set_params = samsung_tbmu24112_tuner_set_params; | ||
494 | 512 | ||
495 | ops->set_voltage = flexcop_set_voltage; | 513 | ops->set_voltage = flexcop_set_voltage; |
496 | 514 | ||
@@ -503,16 +521,19 @@ int flexcop_frontend_init(struct flexcop_device *fc) | |||
503 | /* try the air dvb-t (mt352/Samsung tdtc9251dh0(??)) */ | 521 | /* try the air dvb-t (mt352/Samsung tdtc9251dh0(??)) */ |
504 | if ((fc->fe = mt352_attach(&samsung_tdtc9251dh0_config, &fc->i2c_adap)) != NULL ) { | 522 | if ((fc->fe = mt352_attach(&samsung_tdtc9251dh0_config, &fc->i2c_adap)) != NULL ) { |
505 | fc->dev_type = FC_AIR_DVB; | 523 | fc->dev_type = FC_AIR_DVB; |
524 | fc->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs; | ||
506 | info("found the mt352 at i2c address: 0x%02x",samsung_tdtc9251dh0_config.demod_address); | 525 | info("found the mt352 at i2c address: 0x%02x",samsung_tdtc9251dh0_config.demod_address); |
507 | } else | 526 | } else |
508 | /* try the air atsc 2nd generation (nxt2002) */ | 527 | /* try the air atsc 2nd generation (nxt2002) */ |
509 | if ((fc->fe = nxt200x_attach(&samsung_tbmv_config, &fc->i2c_adap)) != NULL) { | 528 | if ((fc->fe = nxt200x_attach(&samsung_tbmv_config, &fc->i2c_adap)) != NULL) { |
510 | fc->dev_type = FC_AIR_ATSC2; | 529 | fc->dev_type = FC_AIR_ATSC2; |
530 | dvb_pll_attach(fc->fe, 0x61, &fc->i2c_adap, &dvb_pll_samsung_tbmv); | ||
511 | info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address); | 531 | info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address); |
512 | } else | 532 | } else |
513 | /* try the air atsc 3nd generation (lgdt3303) */ | 533 | /* try the air atsc 3nd generation (lgdt3303) */ |
514 | if ((fc->fe = lgdt330x_attach(&air2pc_atsc_hd5000_config, &fc->i2c_adap)) != NULL) { | 534 | if ((fc->fe = lgdt330x_attach(&air2pc_atsc_hd5000_config, &fc->i2c_adap)) != NULL) { |
515 | fc->dev_type = FC_AIR_ATSC3; | 535 | fc->dev_type = FC_AIR_ATSC3; |
536 | fc->fe->ops.tuner_ops.set_params = lgdt3303_tuner_set_params; | ||
516 | info("found the lgdt3303 at i2c address: 0x%02x",air2pc_atsc_hd5000_config.demod_address); | 537 | info("found the lgdt3303 at i2c address: 0x%02x",air2pc_atsc_hd5000_config.demod_address); |
517 | } else | 538 | } else |
518 | /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */ | 539 | /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */ |
@@ -523,11 +544,14 @@ int flexcop_frontend_init(struct flexcop_device *fc) | |||
523 | /* try the cable dvb (stv0297) */ | 544 | /* try the cable dvb (stv0297) */ |
524 | if ((fc->fe = stv0297_attach(&alps_tdee4_stv0297_config, &fc->i2c_adap)) != NULL) { | 545 | if ((fc->fe = stv0297_attach(&alps_tdee4_stv0297_config, &fc->i2c_adap)) != NULL) { |
525 | fc->dev_type = FC_CABLE; | 546 | fc->dev_type = FC_CABLE; |
547 | fc->fe->ops.tuner_ops.set_params = alps_tdee4_stv0297_tuner_set_params; | ||
526 | info("found the stv0297 at i2c address: 0x%02x",alps_tdee4_stv0297_config.demod_address); | 548 | info("found the stv0297 at i2c address: 0x%02x",alps_tdee4_stv0297_config.demod_address); |
527 | } else | 549 | } else |
528 | /* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */ | 550 | /* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */ |
529 | if ((fc->fe = vp310_mt312_attach(&skystar23_samsung_tbdu18132_config, &fc->i2c_adap)) != NULL) { | 551 | if ((fc->fe = vp310_mt312_attach(&skystar23_samsung_tbdu18132_config, &fc->i2c_adap)) != NULL) { |
530 | ops = fc->fe->ops; | 552 | ops = &fc->fe->ops; |
553 | |||
554 | ops->tuner_ops.set_params = skystar23_samsung_tbdu18132_tuner_set_params; | ||
531 | 555 | ||
532 | ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd; | 556 | ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd; |
533 | ops->diseqc_send_burst = flexcop_diseqc_send_burst; | 557 | ops->diseqc_send_burst = flexcop_diseqc_send_burst; |
@@ -547,7 +571,7 @@ int flexcop_frontend_init(struct flexcop_device *fc) | |||
547 | } else { | 571 | } else { |
548 | if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) { | 572 | if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) { |
549 | err("frontend registration failed!"); | 573 | err("frontend registration failed!"); |
550 | ops = fc->fe->ops; | 574 | ops = &fc->fe->ops; |
551 | if (ops->release != NULL) | 575 | if (ops->release != NULL) |
552 | ops->release(fc->fe); | 576 | ops->release(fc->fe); |
553 | fc->fe = NULL; | 577 | fc->fe = NULL; |
diff --git a/drivers/media/dvb/b2c2/flexcop-pci.c b/drivers/media/dvb/b2c2/flexcop-pci.c index 9bc40bdcc282..f04041702191 100644 --- a/drivers/media/dvb/b2c2/flexcop-pci.c +++ b/drivers/media/dvb/b2c2/flexcop-pci.c | |||
@@ -242,19 +242,16 @@ static int flexcop_pci_dma_init(struct flexcop_pci *fc_pci) | |||
242 | if ((ret = flexcop_dma_allocate(fc_pci->pdev,&fc_pci->dma[0],FC_DEFAULT_DMA1_BUFSIZE)) != 0) | 242 | if ((ret = flexcop_dma_allocate(fc_pci->pdev,&fc_pci->dma[0],FC_DEFAULT_DMA1_BUFSIZE)) != 0) |
243 | return ret; | 243 | return ret; |
244 | 244 | ||
245 | if ((ret = flexcop_dma_allocate(fc_pci->pdev,&fc_pci->dma[1],FC_DEFAULT_DMA2_BUFSIZE)) != 0) | 245 | if ((ret = flexcop_dma_allocate(fc_pci->pdev,&fc_pci->dma[1],FC_DEFAULT_DMA2_BUFSIZE)) != 0) { |
246 | goto dma1_free; | 246 | flexcop_dma_free(&fc_pci->dma[0]); |
247 | return ret; | ||
248 | } | ||
247 | 249 | ||
248 | flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_MEDIA | FC_SRAM_DEST_NET, FC_SRAM_DEST_TARGET_DMA1); | 250 | flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_MEDIA | FC_SRAM_DEST_NET, FC_SRAM_DEST_TARGET_DMA1); |
249 | flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_CAO | FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_DMA2); | 251 | flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_CAO | FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_DMA2); |
250 | 252 | ||
251 | fc_pci->init_state |= FC_PCI_DMA_INIT; | 253 | fc_pci->init_state |= FC_PCI_DMA_INIT; |
252 | 254 | ||
253 | goto success; | ||
254 | dma1_free: | ||
255 | flexcop_dma_free(&fc_pci->dma[0]); | ||
256 | |||
257 | success: | ||
258 | return ret; | 255 | return ret; |
259 | } | 256 | } |
260 | 257 | ||
@@ -303,7 +300,7 @@ static int flexcop_pci_init(struct flexcop_pci *fc_pci) | |||
303 | spin_lock_init(&fc_pci->irq_lock); | 300 | spin_lock_init(&fc_pci->irq_lock); |
304 | 301 | ||
305 | fc_pci->init_state |= FC_PCI_INIT; | 302 | fc_pci->init_state |= FC_PCI_INIT; |
306 | goto success; | 303 | return ret; |
307 | 304 | ||
308 | err_pci_iounmap: | 305 | err_pci_iounmap: |
309 | pci_iounmap(fc_pci->pdev, fc_pci->io_mem); | 306 | pci_iounmap(fc_pci->pdev, fc_pci->io_mem); |
@@ -312,8 +309,6 @@ err_pci_release_regions: | |||
312 | pci_release_regions(fc_pci->pdev); | 309 | pci_release_regions(fc_pci->pdev); |
313 | err_pci_disable_device: | 310 | err_pci_disable_device: |
314 | pci_disable_device(fc_pci->pdev); | 311 | pci_disable_device(fc_pci->pdev); |
315 | |||
316 | success: | ||
317 | return ret; | 312 | return ret; |
318 | } | 313 | } |
319 | 314 | ||
@@ -378,14 +373,14 @@ static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
378 | 373 | ||
379 | INIT_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work, fc_pci); | 374 | INIT_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work, fc_pci); |
380 | 375 | ||
381 | goto success; | 376 | return ret; |
377 | |||
382 | err_fc_exit: | 378 | err_fc_exit: |
383 | flexcop_device_exit(fc); | 379 | flexcop_device_exit(fc); |
384 | err_pci_exit: | 380 | err_pci_exit: |
385 | flexcop_pci_exit(fc_pci); | 381 | flexcop_pci_exit(fc_pci); |
386 | err_kfree: | 382 | err_kfree: |
387 | flexcop_device_kfree(fc); | 383 | flexcop_device_kfree(fc); |
388 | success: | ||
389 | return ret; | 384 | return ret; |
390 | } | 385 | } |
391 | 386 | ||
diff --git a/drivers/media/dvb/b2c2/flexcop-usb.c b/drivers/media/dvb/b2c2/flexcop-usb.c index 06ec9fff0ec1..515954f96c9a 100644 --- a/drivers/media/dvb/b2c2/flexcop-usb.c +++ b/drivers/media/dvb/b2c2/flexcop-usb.c | |||
@@ -433,11 +433,10 @@ static int flexcop_usb_transfer_init(struct flexcop_usb *fc_usb) | |||
433 | flexcop_wan_set_speed(fc_usb->fc_dev,FC_WAN_SPEED_8MBITS); | 433 | flexcop_wan_set_speed(fc_usb->fc_dev,FC_WAN_SPEED_8MBITS); |
434 | flexcop_sram_ctrl(fc_usb->fc_dev,1,1,1); | 434 | flexcop_sram_ctrl(fc_usb->fc_dev,1,1,1); |
435 | 435 | ||
436 | ret = 0; | 436 | return 0; |
437 | goto success; | 437 | |
438 | urb_error: | 438 | urb_error: |
439 | flexcop_usb_transfer_exit(fc_usb); | 439 | flexcop_usb_transfer_exit(fc_usb); |
440 | success: | ||
441 | return ret; | 440 | return ret; |
442 | } | 441 | } |
443 | 442 | ||
@@ -515,15 +514,14 @@ static int flexcop_usb_probe(struct usb_interface *intf, | |||
515 | goto err_fc_exit; | 514 | goto err_fc_exit; |
516 | 515 | ||
517 | info("%s successfully initialized and connected.",DRIVER_NAME); | 516 | info("%s successfully initialized and connected.",DRIVER_NAME); |
518 | ret = 0; | 517 | return 0; |
519 | goto success; | 518 | |
520 | err_fc_exit: | 519 | err_fc_exit: |
521 | flexcop_device_exit(fc); | 520 | flexcop_device_exit(fc); |
522 | err_usb_exit: | 521 | err_usb_exit: |
523 | flexcop_usb_exit(fc_usb); | 522 | flexcop_usb_exit(fc_usb); |
524 | err_kfree: | 523 | err_kfree: |
525 | flexcop_device_kfree(fc); | 524 | flexcop_device_kfree(fc); |
526 | success: | ||
527 | return ret; | 525 | return ret; |
528 | } | 526 | } |
529 | 527 | ||
diff --git a/drivers/media/dvb/b2c2/flexcop.c b/drivers/media/dvb/b2c2/flexcop.c index 56ba52470676..29ec4183118e 100644 --- a/drivers/media/dvb/b2c2/flexcop.c +++ b/drivers/media/dvb/b2c2/flexcop.c | |||
@@ -67,7 +67,7 @@ static int flexcop_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) | |||
67 | static int flexcop_dvb_init(struct flexcop_device *fc) | 67 | static int flexcop_dvb_init(struct flexcop_device *fc) |
68 | { | 68 | { |
69 | int ret; | 69 | int ret; |
70 | if ((ret = dvb_register_adapter(&fc->dvb_adapter,"FlexCop Digital TV device",fc->owner)) < 0) { | 70 | if ((ret = dvb_register_adapter(&fc->dvb_adapter,"FlexCop Digital TV device",fc->owner,fc->dev)) < 0) { |
71 | err("error registering DVB adapter"); | 71 | err("error registering DVB adapter"); |
72 | return ret; | 72 | return ret; |
73 | } | 73 | } |
@@ -116,7 +116,7 @@ static int flexcop_dvb_init(struct flexcop_device *fc) | |||
116 | dvb_net_init(&fc->dvb_adapter, &fc->dvbnet, &fc->demux.dmx); | 116 | dvb_net_init(&fc->dvb_adapter, &fc->dvbnet, &fc->demux.dmx); |
117 | 117 | ||
118 | fc->init_state |= FC_STATE_DVB_INIT; | 118 | fc->init_state |= FC_STATE_DVB_INIT; |
119 | goto success; | 119 | return 0; |
120 | 120 | ||
121 | err_connect_frontend: | 121 | err_connect_frontend: |
122 | fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->mem_frontend); | 122 | fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->mem_frontend); |
@@ -129,9 +129,6 @@ err_dmx_dev: | |||
129 | err_dmx: | 129 | err_dmx: |
130 | dvb_unregister_adapter(&fc->dvb_adapter); | 130 | dvb_unregister_adapter(&fc->dvb_adapter); |
131 | return ret; | 131 | return ret; |
132 | |||
133 | success: | ||
134 | return 0; | ||
135 | } | 132 | } |
136 | 133 | ||
137 | static void flexcop_dvb_exit(struct flexcop_device *fc) | 134 | static void flexcop_dvb_exit(struct flexcop_device *fc) |
@@ -279,11 +276,10 @@ int flexcop_device_initialize(struct flexcop_device *fc) | |||
279 | 276 | ||
280 | flexcop_device_name(fc,"initialization of","complete"); | 277 | flexcop_device_name(fc,"initialization of","complete"); |
281 | 278 | ||
282 | ret = 0; | 279 | return 0; |
283 | goto success; | 280 | |
284 | error: | 281 | error: |
285 | flexcop_device_exit(fc); | 282 | flexcop_device_exit(fc); |
286 | success: | ||
287 | return ret; | 283 | return ret; |
288 | } | 284 | } |
289 | EXPORT_SYMBOL(flexcop_device_initialize); | 285 | EXPORT_SYMBOL(flexcop_device_initialize); |
diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/dvb/bt8xx/bt878.c index 5500f8a0ffe2..761fa6e7d762 100644 --- a/drivers/media/dvb/bt8xx/bt878.c +++ b/drivers/media/dvb/bt8xx/bt878.c | |||
@@ -63,8 +63,6 @@ MODULE_PARM_DESC(debug, "Turn on/off debugging, default is 0 (off)."); | |||
63 | int bt878_num; | 63 | int bt878_num; |
64 | struct bt878 bt878[BT878_MAX]; | 64 | struct bt878 bt878[BT878_MAX]; |
65 | 65 | ||
66 | EXPORT_SYMBOL(bt878_debug); | ||
67 | EXPORT_SYMBOL(bt878_verbose); | ||
68 | EXPORT_SYMBOL(bt878_num); | 66 | EXPORT_SYMBOL(bt878_num); |
69 | EXPORT_SYMBOL(bt878); | 67 | EXPORT_SYMBOL(bt878); |
70 | 68 | ||
@@ -393,7 +391,9 @@ static struct cards card_list[] __devinitdata = { | |||
393 | { 0x07711461, BTTV_BOARD_AVDVBT_771, "AVermedia AverTV DVB-T 771" }, | 391 | { 0x07711461, BTTV_BOARD_AVDVBT_771, "AVermedia AverTV DVB-T 771" }, |
394 | { 0xdb1018ac, BTTV_BOARD_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" }, | 392 | { 0xdb1018ac, BTTV_BOARD_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" }, |
395 | { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" }, | 393 | { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" }, |
396 | { 0x20007063, BTTV_BOARD_PC_HDTV, "pcHDTV HD-2000 TV"}, | 394 | { 0x20007063, BTTV_BOARD_PC_HDTV, "pcHDTV HD-2000 TV" }, |
395 | { 0x00261822, BTTV_BOARD_TWINHAN_DST, "DNTV Live! Mini" }, | ||
396 | |||
397 | { 0, -1, NULL } | 397 | { 0, -1, NULL } |
398 | }; | 398 | }; |
399 | 399 | ||
@@ -417,6 +417,11 @@ static int __devinit bt878_probe(struct pci_dev *dev, | |||
417 | 417 | ||
418 | printk(KERN_INFO "bt878: Bt878 AUDIO function found (%d).\n", | 418 | printk(KERN_INFO "bt878: Bt878 AUDIO function found (%d).\n", |
419 | bt878_num); | 419 | bt878_num); |
420 | if (bt878_num >= BT878_MAX) { | ||
421 | printk(KERN_ERR "bt878: Too many devices inserted\n"); | ||
422 | result = -ENOMEM; | ||
423 | goto fail0; | ||
424 | } | ||
420 | if (pci_enable_device(dev)) | 425 | if (pci_enable_device(dev)) |
421 | return -EIO; | 426 | return -EIO; |
422 | 427 | ||
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c index 1cfa5e5035d8..d687a14ec0a7 100644 --- a/drivers/media/dvb/bt8xx/dst.c +++ b/drivers/media/dvb/bt8xx/dst.c | |||
@@ -38,6 +38,10 @@ static unsigned int dst_addons; | |||
38 | module_param(dst_addons, int, 0644); | 38 | module_param(dst_addons, int, 0644); |
39 | MODULE_PARM_DESC(dst_addons, "CA daughterboard, default is 0 (No addons)"); | 39 | MODULE_PARM_DESC(dst_addons, "CA daughterboard, default is 0 (No addons)"); |
40 | 40 | ||
41 | static unsigned int dst_algo; | ||
42 | module_param(dst_algo, int, 0644); | ||
43 | MODULE_PARM_DESC(dst_algo, "tuning algo: default is 0=(SW), 1=(HW)"); | ||
44 | |||
41 | #define HAS_LOCK 1 | 45 | #define HAS_LOCK 1 |
42 | #define ATTEMPT_TUNE 2 | 46 | #define ATTEMPT_TUNE 2 |
43 | #define HAS_POWER 4 | 47 | #define HAS_POWER 4 |
@@ -47,20 +51,24 @@ MODULE_PARM_DESC(dst_addons, "CA daughterboard, default is 0 (No addons)"); | |||
47 | #define DST_INFO 2 | 51 | #define DST_INFO 2 |
48 | #define DST_DEBUG 3 | 52 | #define DST_DEBUG 3 |
49 | 53 | ||
50 | #define dprintk(x, y, z, format, arg...) do { \ | 54 | #define dprintk(x, y, z, format, arg...) do { \ |
51 | if (z) { \ | 55 | if (z) { \ |
52 | if ((x > DST_ERROR) && (x > y)) \ | 56 | if ((x > DST_ERROR) && (x > y)) \ |
53 | printk(KERN_ERR "%s: " format "\n", __FUNCTION__ , ##arg); \ | 57 | printk(KERN_ERR "dst(%d) %s: " format "\n", \ |
54 | else if ((x > DST_NOTICE) && (x > y)) \ | 58 | state->bt->nr, __func__ , ##arg); \ |
55 | printk(KERN_NOTICE "%s: " format "\n", __FUNCTION__ , ##arg); \ | 59 | else if ((x > DST_NOTICE) && (x > y)) \ |
56 | else if ((x > DST_INFO) && (x > y)) \ | 60 | printk(KERN_NOTICE "dst(%d) %s: " format "\n", \ |
57 | printk(KERN_INFO "%s: " format "\n", __FUNCTION__ , ##arg); \ | 61 | state->bt->nr, __func__ , ##arg); \ |
58 | else if ((x > DST_DEBUG) && (x > y)) \ | 62 | else if ((x > DST_INFO) && (x > y)) \ |
59 | printk(KERN_DEBUG "%s: " format "\n", __FUNCTION__ , ##arg); \ | 63 | printk(KERN_INFO "dst(%d) %s: " format "\n", \ |
60 | } else { \ | 64 | state->bt->nr, __func__ , ##arg); \ |
61 | if (x > y) \ | 65 | else if ((x > DST_DEBUG) && (x > y)) \ |
62 | printk(format, ##arg); \ | 66 | printk(KERN_DEBUG "dst(%d) %s: " format "\n", \ |
63 | } \ | 67 | state->bt->nr, __func__ , ##arg); \ |
68 | } else { \ | ||
69 | if (x > y) \ | ||
70 | printk(format, ##arg); \ | ||
71 | } \ | ||
64 | } while(0) | 72 | } while(0) |
65 | 73 | ||
66 | 74 | ||
@@ -110,7 +118,7 @@ int dst_gpio_inb(struct dst_state *state, u8 *result) | |||
110 | 118 | ||
111 | *result = 0; | 119 | *result = 0; |
112 | if ((err = bt878_device_control(state->bt, DST_IG_READ, &rd_packet)) < 0) { | 120 | if ((err = bt878_device_control(state->bt, DST_IG_READ, &rd_packet)) < 0) { |
113 | dprintk(verbose, DST_ERROR, 1, "dst_gpio_inb error (err == %i)\n", err); | 121 | dprintk(verbose, DST_ERROR, 1, "dst_gpio_inb error (err == %i)", err); |
114 | return -EREMOTEIO; | 122 | return -EREMOTEIO; |
115 | } | 123 | } |
116 | *result = (u8) rd_packet.rd.value; | 124 | *result = (u8) rd_packet.rd.value; |
@@ -363,6 +371,17 @@ static int dst_set_freq(struct dst_state *state, u32 freq) | |||
363 | state->tx_tuna[2] = (freq >> 16) & 0xff; | 371 | state->tx_tuna[2] = (freq >> 16) & 0xff; |
364 | state->tx_tuna[3] = (freq >> 8) & 0xff; | 372 | state->tx_tuna[3] = (freq >> 8) & 0xff; |
365 | state->tx_tuna[4] = (u8) freq; | 373 | state->tx_tuna[4] = (u8) freq; |
374 | } else if (state->dst_type == DST_TYPE_IS_ATSC) { | ||
375 | freq = freq / 1000; | ||
376 | if (freq < 51000 || freq > 858000) | ||
377 | return -EINVAL; | ||
378 | state->tx_tuna[2] = (freq >> 16) & 0xff; | ||
379 | state->tx_tuna[3] = (freq >> 8) & 0xff; | ||
380 | state->tx_tuna[4] = (u8) freq; | ||
381 | state->tx_tuna[5] = 0x00; /* ATSC */ | ||
382 | state->tx_tuna[6] = 0x00; | ||
383 | if (state->dst_hw_cap & DST_TYPE_HAS_ANALOG) | ||
384 | state->tx_tuna[7] = 0x00; /* Digital */ | ||
366 | } else | 385 | } else |
367 | return -EINVAL; | 386 | return -EINVAL; |
368 | 387 | ||
@@ -447,29 +466,41 @@ static int dst_set_symbolrate(struct dst_state *state, u32 srate) | |||
447 | } | 466 | } |
448 | dprintk(verbose, DST_INFO, 1, "set symrate %u", srate); | 467 | dprintk(verbose, DST_INFO, 1, "set symrate %u", srate); |
449 | srate /= 1000; | 468 | srate /= 1000; |
450 | if (state->type_flags & DST_TYPE_HAS_SYMDIV) { | 469 | if (state->dst_type == DST_TYPE_IS_SAT) { |
451 | sval = srate; | 470 | if (state->type_flags & DST_TYPE_HAS_SYMDIV) { |
452 | sval <<= 20; | 471 | sval = srate; |
453 | do_div(sval, 88000); | 472 | sval <<= 20; |
454 | symcalc = (u32) sval; | 473 | do_div(sval, 88000); |
455 | dprintk(verbose, DST_INFO, 1, "set symcalc %u", symcalc); | 474 | symcalc = (u32) sval; |
456 | state->tx_tuna[5] = (u8) (symcalc >> 12); | 475 | dprintk(verbose, DST_INFO, 1, "set symcalc %u", symcalc); |
457 | state->tx_tuna[6] = (u8) (symcalc >> 4); | 476 | state->tx_tuna[5] = (u8) (symcalc >> 12); |
458 | state->tx_tuna[7] = (u8) (symcalc << 4); | 477 | state->tx_tuna[6] = (u8) (symcalc >> 4); |
459 | } else { | 478 | state->tx_tuna[7] = (u8) (symcalc << 4); |
460 | state->tx_tuna[5] = (u8) (srate >> 16) & 0x7f; | 479 | } else { |
461 | state->tx_tuna[6] = (u8) (srate >> 8); | 480 | state->tx_tuna[5] = (u8) (srate >> 16) & 0x7f; |
462 | state->tx_tuna[7] = (u8) srate; | 481 | state->tx_tuna[6] = (u8) (srate >> 8); |
463 | } | 482 | state->tx_tuna[7] = (u8) srate; |
464 | state->tx_tuna[8] &= ~0x20; | 483 | } |
465 | if (state->type_flags & DST_TYPE_HAS_OBS_REGS) { | 484 | state->tx_tuna[8] &= ~0x20; |
466 | if (srate > 8000) | 485 | if (state->type_flags & DST_TYPE_HAS_OBS_REGS) { |
467 | state->tx_tuna[8] |= 0x20; | 486 | if (srate > 8000) |
487 | state->tx_tuna[8] |= 0x20; | ||
488 | } | ||
489 | } else if (state->dst_type == DST_TYPE_IS_CABLE) { | ||
490 | dprintk(verbose, DST_DEBUG, 1, "%s", state->fw_name); | ||
491 | if (!strncmp(state->fw_name, "DCTNEW", 6)) { | ||
492 | state->tx_tuna[5] = (u8) (srate >> 8); | ||
493 | state->tx_tuna[6] = (u8) srate; | ||
494 | state->tx_tuna[7] = 0x00; | ||
495 | } else if (!strncmp(state->fw_name, "DCT-CI", 6)) { | ||
496 | state->tx_tuna[5] = 0x00; | ||
497 | state->tx_tuna[6] = (u8) (srate >> 8); | ||
498 | state->tx_tuna[7] = (u8) srate; | ||
499 | } | ||
468 | } | 500 | } |
469 | return 0; | 501 | return 0; |
470 | } | 502 | } |
471 | 503 | ||
472 | |||
473 | static int dst_set_modulation(struct dst_state *state, fe_modulation_t modulation) | 504 | static int dst_set_modulation(struct dst_state *state, fe_modulation_t modulation) |
474 | { | 505 | { |
475 | if (state->dst_type != DST_TYPE_IS_CABLE) | 506 | if (state->dst_type != DST_TYPE_IS_CABLE) |
@@ -490,7 +521,10 @@ static int dst_set_modulation(struct dst_state *state, fe_modulation_t modulatio | |||
490 | state->tx_tuna[8] = 0x80; | 521 | state->tx_tuna[8] = 0x80; |
491 | break; | 522 | break; |
492 | case QAM_256: | 523 | case QAM_256: |
493 | state->tx_tuna[8] = 0x00; | 524 | if (!strncmp(state->fw_name, "DCTNEW", 6)) |
525 | state->tx_tuna[8] = 0xff; | ||
526 | else if (!strncmp(state->fw_name, "DCT-CI", 6)) | ||
527 | state->tx_tuna[8] = 0x00; | ||
494 | break; | 528 | break; |
495 | case QPSK: | 529 | case QPSK: |
496 | case QAM_AUTO: | 530 | case QAM_AUTO: |
@@ -523,13 +557,19 @@ u8 dst_check_sum(u8 *buf, u32 len) | |||
523 | } | 557 | } |
524 | EXPORT_SYMBOL(dst_check_sum); | 558 | EXPORT_SYMBOL(dst_check_sum); |
525 | 559 | ||
526 | static void dst_type_flags_print(u32 type_flags) | 560 | static void dst_type_flags_print(struct dst_state *state) |
527 | { | 561 | { |
562 | u32 type_flags = state->type_flags; | ||
563 | |||
528 | dprintk(verbose, DST_ERROR, 0, "DST type flags :"); | 564 | dprintk(verbose, DST_ERROR, 0, "DST type flags :"); |
529 | if (type_flags & DST_TYPE_HAS_NEWTUNE) | 565 | if (type_flags & DST_TYPE_HAS_TS188) |
530 | dprintk(verbose, DST_ERROR, 0, " 0x%x newtuner", DST_TYPE_HAS_NEWTUNE); | 566 | dprintk(verbose, DST_ERROR, 0, " 0x%x newtuner", DST_TYPE_HAS_TS188); |
567 | if (type_flags & DST_TYPE_HAS_NEWTUNE_2) | ||
568 | dprintk(verbose, DST_ERROR, 0, " 0x%x newtuner 2", DST_TYPE_HAS_NEWTUNE_2); | ||
531 | if (type_flags & DST_TYPE_HAS_TS204) | 569 | if (type_flags & DST_TYPE_HAS_TS204) |
532 | dprintk(verbose, DST_ERROR, 0, " 0x%x ts204", DST_TYPE_HAS_TS204); | 570 | dprintk(verbose, DST_ERROR, 0, " 0x%x ts204", DST_TYPE_HAS_TS204); |
571 | if (type_flags & DST_TYPE_HAS_VLF) | ||
572 | dprintk(verbose, DST_ERROR, 0, " 0x%x VLF", DST_TYPE_HAS_VLF); | ||
533 | if (type_flags & DST_TYPE_HAS_SYMDIV) | 573 | if (type_flags & DST_TYPE_HAS_SYMDIV) |
534 | dprintk(verbose, DST_ERROR, 0, " 0x%x symdiv", DST_TYPE_HAS_SYMDIV); | 574 | dprintk(verbose, DST_ERROR, 0, " 0x%x symdiv", DST_TYPE_HAS_SYMDIV); |
535 | if (type_flags & DST_TYPE_HAS_FW_1) | 575 | if (type_flags & DST_TYPE_HAS_FW_1) |
@@ -542,7 +582,7 @@ static void dst_type_flags_print(u32 type_flags) | |||
542 | } | 582 | } |
543 | 583 | ||
544 | 584 | ||
545 | static int dst_type_print(u8 type) | 585 | static int dst_type_print(struct dst_state *state, u8 type) |
546 | { | 586 | { |
547 | char *otype; | 587 | char *otype; |
548 | switch (type) { | 588 | switch (type) { |
@@ -558,6 +598,10 @@ static int dst_type_print(u8 type) | |||
558 | otype = "cable"; | 598 | otype = "cable"; |
559 | break; | 599 | break; |
560 | 600 | ||
601 | case DST_TYPE_IS_ATSC: | ||
602 | otype = "atsc"; | ||
603 | break; | ||
604 | |||
561 | default: | 605 | default: |
562 | dprintk(verbose, DST_INFO, 1, "invalid dst type %d", type); | 606 | dprintk(verbose, DST_INFO, 1, "invalid dst type %d", type); |
563 | return -EINVAL; | 607 | return -EINVAL; |
@@ -567,6 +611,127 @@ static int dst_type_print(u8 type) | |||
567 | return 0; | 611 | return 0; |
568 | } | 612 | } |
569 | 613 | ||
614 | struct tuner_types tuner_list[] = { | ||
615 | { | ||
616 | .tuner_type = TUNER_TYPE_L64724, | ||
617 | .tuner_name = "L 64724", | ||
618 | .board_name = "UNKNOWN", | ||
619 | .fw_name = "UNKNOWN" | ||
620 | }, | ||
621 | |||
622 | { | ||
623 | .tuner_type = TUNER_TYPE_STV0299, | ||
624 | .tuner_name = "STV 0299", | ||
625 | .board_name = "VP1020", | ||
626 | .fw_name = "DST-MOT" | ||
627 | }, | ||
628 | |||
629 | { | ||
630 | .tuner_type = TUNER_TYPE_STV0299, | ||
631 | .tuner_name = "STV 0299", | ||
632 | .board_name = "VP1020", | ||
633 | .fw_name = "DST-03T" | ||
634 | }, | ||
635 | |||
636 | { | ||
637 | .tuner_type = TUNER_TYPE_MB86A15, | ||
638 | .tuner_name = "MB 86A15", | ||
639 | .board_name = "VP1022", | ||
640 | .fw_name = "DST-03T" | ||
641 | }, | ||
642 | |||
643 | { | ||
644 | .tuner_type = TUNER_TYPE_MB86A15, | ||
645 | .tuner_name = "MB 86A15", | ||
646 | .board_name = "VP1025", | ||
647 | .fw_name = "DST-03T" | ||
648 | }, | ||
649 | |||
650 | { | ||
651 | .tuner_type = TUNER_TYPE_STV0299, | ||
652 | .tuner_name = "STV 0299", | ||
653 | .board_name = "VP1030", | ||
654 | .fw_name = "DST-CI" | ||
655 | }, | ||
656 | |||
657 | { | ||
658 | .tuner_type = TUNER_TYPE_STV0299, | ||
659 | .tuner_name = "STV 0299", | ||
660 | .board_name = "VP1030", | ||
661 | .fw_name = "DSTMCI" | ||
662 | }, | ||
663 | |||
664 | { | ||
665 | .tuner_type = TUNER_TYPE_UNKNOWN, | ||
666 | .tuner_name = "UNKNOWN", | ||
667 | .board_name = "VP2021", | ||
668 | .fw_name = "DCTNEW" | ||
669 | }, | ||
670 | |||
671 | { | ||
672 | .tuner_type = TUNER_TYPE_UNKNOWN, | ||
673 | .tuner_name = "UNKNOWN", | ||
674 | .board_name = "VP2030", | ||
675 | .fw_name = "DCT-CI" | ||
676 | }, | ||
677 | |||
678 | { | ||
679 | .tuner_type = TUNER_TYPE_UNKNOWN, | ||
680 | .tuner_name = "UNKNOWN", | ||
681 | .board_name = "VP2031", | ||
682 | .fw_name = "DCT-CI" | ||
683 | }, | ||
684 | |||
685 | { | ||
686 | .tuner_type = TUNER_TYPE_UNKNOWN, | ||
687 | .tuner_name = "UNKNOWN", | ||
688 | .board_name = "VP2040", | ||
689 | .fw_name = "DCT-CI" | ||
690 | }, | ||
691 | |||
692 | { | ||
693 | .tuner_type = TUNER_TYPE_UNKNOWN, | ||
694 | .tuner_name = "UNKNOWN", | ||
695 | .board_name = "VP3020", | ||
696 | .fw_name = "DTTFTA" | ||
697 | }, | ||
698 | |||
699 | { | ||
700 | .tuner_type = TUNER_TYPE_UNKNOWN, | ||
701 | .tuner_name = "UNKNOWN", | ||
702 | .board_name = "VP3021", | ||
703 | .fw_name = "DTTFTA" | ||
704 | }, | ||
705 | |||
706 | { | ||
707 | .tuner_type = TUNER_TYPE_TDA10046, | ||
708 | .tuner_name = "TDA10046", | ||
709 | .board_name = "VP3040", | ||
710 | .fw_name = "DTT-CI" | ||
711 | }, | ||
712 | |||
713 | { | ||
714 | .tuner_type = TUNER_TYPE_UNKNOWN, | ||
715 | .tuner_name = "UNKNOWN", | ||
716 | .board_name = "VP3051", | ||
717 | .fw_name = "DTTNXT" | ||
718 | }, | ||
719 | |||
720 | { | ||
721 | .tuner_type = TUNER_TYPE_NXT200x, | ||
722 | .tuner_name = "NXT200x", | ||
723 | .board_name = "VP3220", | ||
724 | .fw_name = "ATSCDI" | ||
725 | }, | ||
726 | |||
727 | { | ||
728 | .tuner_type = TUNER_TYPE_NXT200x, | ||
729 | .tuner_name = "NXT200x", | ||
730 | .board_name = "VP3250", | ||
731 | .fw_name = "ATSCAD" | ||
732 | }, | ||
733 | }; | ||
734 | |||
570 | /* | 735 | /* |
571 | Known cards list | 736 | Known cards list |
572 | Satellite | 737 | Satellite |
@@ -608,7 +773,8 @@ static struct dst_types dst_tlist[] = { | |||
608 | .offset = 0, | 773 | .offset = 0, |
609 | .dst_type = DST_TYPE_IS_SAT, | 774 | .dst_type = DST_TYPE_IS_SAT, |
610 | .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_OBS_REGS, | 775 | .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_OBS_REGS, |
611 | .dst_feature = 0 | 776 | .dst_feature = 0, |
777 | .tuner_type = 0 | ||
612 | }, /* obsolete */ | 778 | }, /* obsolete */ |
613 | 779 | ||
614 | { | 780 | { |
@@ -616,15 +782,17 @@ static struct dst_types dst_tlist[] = { | |||
616 | .offset = 0, | 782 | .offset = 0, |
617 | .dst_type = DST_TYPE_IS_SAT, | 783 | .dst_type = DST_TYPE_IS_SAT, |
618 | .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1, | 784 | .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1, |
619 | .dst_feature = 0 | 785 | .dst_feature = 0, |
786 | .tuner_type = 0 | ||
620 | }, /* obsolete */ | 787 | }, /* obsolete */ |
621 | 788 | ||
622 | { | 789 | { |
623 | .device_id = "DST-030", | 790 | .device_id = "DST-030", |
624 | .offset = 0, | 791 | .offset = 0, |
625 | .dst_type = DST_TYPE_IS_SAT, | 792 | .dst_type = DST_TYPE_IS_SAT, |
626 | .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1, | 793 | .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_1, |
627 | .dst_feature = 0 | 794 | .dst_feature = 0, |
795 | .tuner_type = 0 | ||
628 | }, /* obsolete */ | 796 | }, /* obsolete */ |
629 | 797 | ||
630 | { | 798 | { |
@@ -633,7 +801,8 @@ static struct dst_types dst_tlist[] = { | |||
633 | .dst_type = DST_TYPE_IS_SAT, | 801 | .dst_type = DST_TYPE_IS_SAT, |
634 | .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2, | 802 | .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2, |
635 | .dst_feature = DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 | DST_TYPE_HAS_DISEQC5 | 803 | .dst_feature = DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 | DST_TYPE_HAS_DISEQC5 |
636 | | DST_TYPE_HAS_MAC | DST_TYPE_HAS_MOTO | 804 | | DST_TYPE_HAS_MAC | DST_TYPE_HAS_MOTO, |
805 | .tuner_type = TUNER_TYPE_MULTI | ||
637 | }, | 806 | }, |
638 | 807 | ||
639 | { | 808 | { |
@@ -641,57 +810,63 @@ static struct dst_types dst_tlist[] = { | |||
641 | .offset = 0, | 810 | .offset = 0, |
642 | .dst_type = DST_TYPE_IS_SAT, | 811 | .dst_type = DST_TYPE_IS_SAT, |
643 | .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1, | 812 | .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1, |
644 | .dst_feature = 0 | 813 | .dst_feature = 0, |
814 | .tuner_type = 0 | ||
645 | }, /* obsolete */ | 815 | }, /* obsolete */ |
646 | 816 | ||
647 | { | 817 | { |
648 | .device_id = "DST-CI", | 818 | .device_id = "DST-CI", |
649 | .offset = 1, | 819 | .offset = 1, |
650 | .dst_type = DST_TYPE_IS_SAT, | 820 | .dst_type = DST_TYPE_IS_SAT, |
651 | .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1, | 821 | .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_1, |
652 | .dst_feature = DST_TYPE_HAS_CA | 822 | .dst_feature = DST_TYPE_HAS_CA, |
823 | .tuner_type = 0 | ||
653 | }, /* An OEM board */ | 824 | }, /* An OEM board */ |
654 | 825 | ||
655 | { | 826 | { |
656 | .device_id = "DSTMCI", | 827 | .device_id = "DSTMCI", |
657 | .offset = 1, | 828 | .offset = 1, |
658 | .dst_type = DST_TYPE_IS_SAT, | 829 | .dst_type = DST_TYPE_IS_SAT, |
659 | .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_INC_COUNT, | 830 | .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_INC_COUNT | DST_TYPE_HAS_VLF, |
660 | .dst_feature = DST_TYPE_HAS_CA | DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 | 831 | .dst_feature = DST_TYPE_HAS_CA | DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 |
661 | | DST_TYPE_HAS_MOTO | DST_TYPE_HAS_MAC | 832 | | DST_TYPE_HAS_MOTO | DST_TYPE_HAS_MAC, |
833 | .tuner_type = TUNER_TYPE_MULTI | ||
662 | }, | 834 | }, |
663 | 835 | ||
664 | { | 836 | { |
665 | .device_id = "DSTFCI", | 837 | .device_id = "DSTFCI", |
666 | .offset = 1, | 838 | .offset = 1, |
667 | .dst_type = DST_TYPE_IS_SAT, | 839 | .dst_type = DST_TYPE_IS_SAT, |
668 | .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1, | 840 | .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_1, |
669 | .dst_feature = 0 | 841 | .dst_feature = 0, |
842 | .tuner_type = 0 | ||
670 | }, /* unknown to vendor */ | 843 | }, /* unknown to vendor */ |
671 | 844 | ||
672 | { | 845 | { |
673 | .device_id = "DCT-CI", | 846 | .device_id = "DCT-CI", |
674 | .offset = 1, | 847 | .offset = 1, |
675 | .dst_type = DST_TYPE_IS_CABLE, | 848 | .dst_type = DST_TYPE_IS_CABLE, |
676 | .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1 | 849 | .type_flags = DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_VLF, |
677 | | DST_TYPE_HAS_FW_2, | 850 | .dst_feature = DST_TYPE_HAS_CA, |
678 | .dst_feature = DST_TYPE_HAS_CA | 851 | .tuner_type = 0 |
679 | }, | 852 | }, |
680 | 853 | ||
681 | { | 854 | { |
682 | .device_id = "DCTNEW", | 855 | .device_id = "DCTNEW", |
683 | .offset = 1, | 856 | .offset = 1, |
684 | .dst_type = DST_TYPE_IS_CABLE, | 857 | .dst_type = DST_TYPE_IS_CABLE, |
685 | .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_3 | DST_TYPE_HAS_FW_BUILD, | 858 | .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_3 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_MULTI_FE, |
686 | .dst_feature = 0 | 859 | .dst_feature = 0, |
860 | .tuner_type = 0 | ||
687 | }, | 861 | }, |
688 | 862 | ||
689 | { | 863 | { |
690 | .device_id = "DTT-CI", | 864 | .device_id = "DTT-CI", |
691 | .offset = 1, | 865 | .offset = 1, |
692 | .dst_type = DST_TYPE_IS_TERR, | 866 | .dst_type = DST_TYPE_IS_TERR, |
693 | .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_MULTI_FE, | 867 | .type_flags = DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_VLF, |
694 | .dst_feature = DST_TYPE_HAS_CA | 868 | .dst_feature = DST_TYPE_HAS_CA, |
869 | .tuner_type = 0 | ||
695 | }, | 870 | }, |
696 | 871 | ||
697 | { | 872 | { |
@@ -699,7 +874,8 @@ static struct dst_types dst_tlist[] = { | |||
699 | .offset = 1, | 874 | .offset = 1, |
700 | .dst_type = DST_TYPE_IS_TERR, | 875 | .dst_type = DST_TYPE_IS_TERR, |
701 | .type_flags = DST_TYPE_HAS_FW_2, | 876 | .type_flags = DST_TYPE_HAS_FW_2, |
702 | .dst_feature = 0 | 877 | .dst_feature = 0, |
878 | .tuner_type = 0 | ||
703 | }, | 879 | }, |
704 | 880 | ||
705 | { | 881 | { |
@@ -707,7 +883,8 @@ static struct dst_types dst_tlist[] = { | |||
707 | .offset = 1, | 883 | .offset = 1, |
708 | .dst_type = DST_TYPE_IS_TERR, | 884 | .dst_type = DST_TYPE_IS_TERR, |
709 | .type_flags = DST_TYPE_HAS_FW_2, | 885 | .type_flags = DST_TYPE_HAS_FW_2, |
710 | .dst_feature = DST_TYPE_HAS_ANALOG | 886 | .dst_feature = DST_TYPE_HAS_ANALOG, |
887 | .tuner_type = 0 | ||
711 | }, | 888 | }, |
712 | 889 | ||
713 | { | 890 | { |
@@ -715,15 +892,17 @@ static struct dst_types dst_tlist[] = { | |||
715 | .offset = 1, | 892 | .offset = 1, |
716 | .dst_type = DST_TYPE_IS_ATSC, | 893 | .dst_type = DST_TYPE_IS_ATSC, |
717 | .type_flags = DST_TYPE_HAS_FW_2, | 894 | .type_flags = DST_TYPE_HAS_FW_2, |
718 | .dst_feature = 0 | 895 | .dst_feature = 0, |
896 | .tuner_type = 0 | ||
719 | }, | 897 | }, |
720 | 898 | ||
721 | { | 899 | { |
722 | .device_id = "ATSCAD", | 900 | .device_id = "ATSCAD", |
723 | .offset = 1, | 901 | .offset = 1, |
724 | .dst_type = DST_TYPE_IS_ATSC, | 902 | .dst_type = DST_TYPE_IS_ATSC, |
725 | .type_flags = DST_TYPE_HAS_FW_2, | 903 | .type_flags = DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD, |
726 | .dst_feature = 0 | 904 | .dst_feature = DST_TYPE_HAS_MAC | DST_TYPE_HAS_ANALOG, |
905 | .tuner_type = 0 | ||
727 | }, | 906 | }, |
728 | 907 | ||
729 | { } | 908 | { } |
@@ -768,6 +947,9 @@ static int dst_fw_ver(struct dst_state *state) | |||
768 | 947 | ||
769 | static int dst_card_type(struct dst_state *state) | 948 | static int dst_card_type(struct dst_state *state) |
770 | { | 949 | { |
950 | int j; | ||
951 | struct tuner_types *p_tuner_list = NULL; | ||
952 | |||
771 | u8 get_type[] = { 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | 953 | u8 get_type[] = { 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; |
772 | get_type[7] = dst_check_sum(get_type, 7); | 954 | get_type[7] = dst_check_sum(get_type, 7); |
773 | if (dst_command(state, get_type, 8) < 0) { | 955 | if (dst_command(state, get_type, 8) < 0) { |
@@ -775,9 +957,17 @@ static int dst_card_type(struct dst_state *state) | |||
775 | return -1; | 957 | return -1; |
776 | } | 958 | } |
777 | memset(&state->card_info, '\0', 8); | 959 | memset(&state->card_info, '\0', 8); |
778 | memcpy(&state->card_info, &state->rxbuffer, 8); | 960 | memcpy(&state->card_info, &state->rxbuffer, 7); |
779 | dprintk(verbose, DST_ERROR, 1, "Device Model=[%s]", &state->card_info[0]); | 961 | dprintk(verbose, DST_ERROR, 1, "Device Model=[%s]", &state->card_info[0]); |
780 | 962 | ||
963 | for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) { | ||
964 | if (!strcmp(&state->card_info[0], p_tuner_list->board_name)) { | ||
965 | state->tuner_type = p_tuner_list->tuner_type; | ||
966 | dprintk(verbose, DST_ERROR, 1, "DST has [%s] tuner, tuner type=[%d]", | ||
967 | p_tuner_list->tuner_name, p_tuner_list->tuner_type); | ||
968 | } | ||
969 | } | ||
970 | |||
781 | return 0; | 971 | return 0; |
782 | } | 972 | } |
783 | 973 | ||
@@ -790,12 +980,64 @@ static int dst_get_vendor(struct dst_state *state) | |||
790 | return -1; | 980 | return -1; |
791 | } | 981 | } |
792 | memset(&state->vendor, '\0', 8); | 982 | memset(&state->vendor, '\0', 8); |
793 | memcpy(&state->vendor, &state->rxbuffer, 8); | 983 | memcpy(&state->vendor, &state->rxbuffer, 7); |
794 | dprintk(verbose, DST_ERROR, 1, "Vendor=[%s]", &state->vendor[0]); | 984 | dprintk(verbose, DST_ERROR, 1, "Vendor=[%s]", &state->vendor[0]); |
795 | 985 | ||
796 | return 0; | 986 | return 0; |
797 | } | 987 | } |
798 | 988 | ||
989 | static void debug_dst_buffer(struct dst_state *state) | ||
990 | { | ||
991 | int i; | ||
992 | |||
993 | if (verbose > 2) { | ||
994 | printk("%s: [", __func__); | ||
995 | for (i = 0; i < 8; i++) | ||
996 | printk(" %02x", state->rxbuffer[i]); | ||
997 | printk("]\n"); | ||
998 | } | ||
999 | } | ||
1000 | |||
1001 | static int dst_check_stv0299(struct dst_state *state) | ||
1002 | { | ||
1003 | u8 check_stv0299[] = { 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | ||
1004 | |||
1005 | check_stv0299[7] = dst_check_sum(check_stv0299, 7); | ||
1006 | if (dst_command(state, check_stv0299, 8) < 0) { | ||
1007 | dprintk(verbose, DST_ERROR, 1, "Cmd=[0x04] failed"); | ||
1008 | return -1; | ||
1009 | } | ||
1010 | debug_dst_buffer(state); | ||
1011 | |||
1012 | if (memcmp(&check_stv0299, &state->rxbuffer, 8)) { | ||
1013 | dprintk(verbose, DST_ERROR, 1, "Found a STV0299 NIM"); | ||
1014 | state->tuner_type = TUNER_TYPE_STV0299; | ||
1015 | return 0; | ||
1016 | } | ||
1017 | |||
1018 | return -1; | ||
1019 | } | ||
1020 | |||
1021 | static int dst_check_mb86a15(struct dst_state *state) | ||
1022 | { | ||
1023 | u8 check_mb86a15[] = { 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | ||
1024 | |||
1025 | check_mb86a15[7] = dst_check_sum(check_mb86a15, 7); | ||
1026 | if (dst_command(state, check_mb86a15, 8) < 0) { | ||
1027 | dprintk(verbose, DST_ERROR, 1, "Cmd=[0x10], failed"); | ||
1028 | return -1; | ||
1029 | } | ||
1030 | debug_dst_buffer(state); | ||
1031 | |||
1032 | if (memcmp(&check_mb86a15, &state->rxbuffer, 8) < 0) { | ||
1033 | dprintk(verbose, DST_ERROR, 1, "Found a MB86A15 NIM"); | ||
1034 | state->tuner_type = TUNER_TYPE_MB86A15; | ||
1035 | return 0; | ||
1036 | } | ||
1037 | |||
1038 | return -1; | ||
1039 | } | ||
1040 | |||
799 | static int dst_get_tuner_info(struct dst_state *state) | 1041 | static int dst_get_tuner_info(struct dst_state *state) |
800 | { | 1042 | { |
801 | u8 get_tuner_1[] = { 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | 1043 | u8 get_tuner_1[] = { 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; |
@@ -803,60 +1045,59 @@ static int dst_get_tuner_info(struct dst_state *state) | |||
803 | 1045 | ||
804 | get_tuner_1[7] = dst_check_sum(get_tuner_1, 7); | 1046 | get_tuner_1[7] = dst_check_sum(get_tuner_1, 7); |
805 | get_tuner_2[7] = dst_check_sum(get_tuner_2, 7); | 1047 | get_tuner_2[7] = dst_check_sum(get_tuner_2, 7); |
1048 | dprintk(verbose, DST_ERROR, 1, "DST TYpe = MULTI FE"); | ||
806 | if (state->type_flags & DST_TYPE_HAS_MULTI_FE) { | 1049 | if (state->type_flags & DST_TYPE_HAS_MULTI_FE) { |
807 | if (dst_command(state, get_tuner_2, 8) < 0) { | 1050 | if (dst_command(state, get_tuner_1, 8) < 0) { |
808 | dprintk(verbose, DST_INFO, 1, "Unsupported Command"); | 1051 | dprintk(verbose, DST_INFO, 1, "Cmd=[0x13], Unsupported"); |
809 | return -1; | 1052 | goto force; |
810 | } | 1053 | } |
811 | } else { | 1054 | } else { |
812 | if (dst_command(state, get_tuner_1, 8) < 0) { | 1055 | if (dst_command(state, get_tuner_2, 8) < 0) { |
813 | dprintk(verbose, DST_INFO, 1, "Unsupported Command"); | 1056 | dprintk(verbose, DST_INFO, 1, "Cmd=[0xb], Unsupported"); |
814 | return -1; | 1057 | goto force; |
815 | } | 1058 | } |
816 | } | 1059 | } |
817 | memset(&state->board_info, '\0', 8); | 1060 | memset(&state->board_info, '\0', 8); |
818 | memcpy(&state->board_info, &state->rxbuffer, 8); | 1061 | memcpy(&state->board_info, &state->rxbuffer, 8); |
819 | if (state->type_flags & DST_TYPE_HAS_MULTI_FE) { | 1062 | if (state->type_flags & DST_TYPE_HAS_MULTI_FE) { |
820 | if (state->board_info[1] == 0x0b) { | 1063 | dprintk(verbose, DST_ERROR, 1, "DST type has TS=188"); |
821 | if (state->type_flags & DST_TYPE_HAS_TS204) | 1064 | } |
822 | state->type_flags &= ~DST_TYPE_HAS_TS204; | 1065 | if (state->board_info[0] == 0xbc) { |
823 | state->type_flags |= DST_TYPE_HAS_NEWTUNE; | 1066 | if (state->type_flags != DST_TYPE_IS_ATSC) |
824 | dprintk(verbose, DST_INFO, 1, "DST type has TS=188"); | 1067 | state->type_flags |= DST_TYPE_HAS_TS188; |
825 | } else { | 1068 | else |
826 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) | 1069 | state->type_flags |= DST_TYPE_HAS_NEWTUNE_2; |
827 | state->type_flags &= ~DST_TYPE_HAS_NEWTUNE; | 1070 | |
828 | state->type_flags |= DST_TYPE_HAS_TS204; | 1071 | if (state->board_info[1] == 0x01) { |
829 | dprintk(verbose, DST_INFO, 1, "DST type has TS=204"); | 1072 | state->dst_hw_cap |= DST_TYPE_HAS_DBOARD; |
830 | } | 1073 | dprintk(verbose, DST_ERROR, 1, "DST has Daughterboard"); |
831 | } else { | ||
832 | if (state->board_info[0] == 0xbc) { | ||
833 | if (state->type_flags & DST_TYPE_HAS_TS204) | ||
834 | state->type_flags &= ~DST_TYPE_HAS_TS204; | ||
835 | state->type_flags |= DST_TYPE_HAS_NEWTUNE; | ||
836 | dprintk(verbose, DST_INFO, 1, "DST type has TS=188, Daughterboard=[%d]", state->board_info[1]); | ||
837 | |||
838 | } else if (state->board_info[0] == 0xcc) { | ||
839 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) | ||
840 | state->type_flags &= ~DST_TYPE_HAS_NEWTUNE; | ||
841 | state->type_flags |= DST_TYPE_HAS_TS204; | ||
842 | dprintk(verbose, DST_INFO, 1, "DST type has TS=204 Daughterboard=[%d]", state->board_info[1]); | ||
843 | } | 1074 | } |
844 | } | 1075 | } |
845 | 1076 | ||
846 | return 0; | 1077 | return 0; |
1078 | force: | ||
1079 | if (!strncmp(state->fw_name, "DCT-CI", 6)) { | ||
1080 | state->type_flags |= DST_TYPE_HAS_TS204; | ||
1081 | dprintk(verbose, DST_ERROR, 1, "Forcing [%s] to TS188", state->fw_name); | ||
1082 | } | ||
1083 | |||
1084 | return -1; | ||
847 | } | 1085 | } |
848 | 1086 | ||
849 | static int dst_get_device_id(struct dst_state *state) | 1087 | static int dst_get_device_id(struct dst_state *state) |
850 | { | 1088 | { |
851 | u8 reply; | 1089 | u8 reply; |
852 | 1090 | ||
853 | int i; | 1091 | int i, j; |
854 | struct dst_types *p_dst_type; | 1092 | struct dst_types *p_dst_type = NULL; |
1093 | struct tuner_types *p_tuner_list = NULL; | ||
1094 | |||
855 | u8 use_dst_type = 0; | 1095 | u8 use_dst_type = 0; |
856 | u32 use_type_flags = 0; | 1096 | u32 use_type_flags = 0; |
857 | 1097 | ||
858 | static u8 device_type[8] = {0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}; | 1098 | static u8 device_type[8] = {0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}; |
859 | 1099 | ||
1100 | state->tuner_type = 0; | ||
860 | device_type[7] = dst_check_sum(device_type, 7); | 1101 | device_type[7] = dst_check_sum(device_type, 7); |
861 | 1102 | ||
862 | if (write_dst(state, device_type, FIXED_COMM)) | 1103 | if (write_dst(state, device_type, FIXED_COMM)) |
@@ -888,8 +1129,34 @@ static int dst_get_device_id(struct dst_state *state) | |||
888 | 1129 | ||
889 | /* Card capabilities */ | 1130 | /* Card capabilities */ |
890 | state->dst_hw_cap = p_dst_type->dst_feature; | 1131 | state->dst_hw_cap = p_dst_type->dst_feature; |
891 | dprintk(verbose, DST_ERROR, 1, "Recognise [%s]\n", p_dst_type->device_id); | 1132 | dprintk(verbose, DST_ERROR, 1, "Recognise [%s]", p_dst_type->device_id); |
892 | 1133 | strncpy(&state->fw_name[0], p_dst_type->device_id, 6); | |
1134 | /* Multiple tuners */ | ||
1135 | if (p_dst_type->tuner_type & TUNER_TYPE_MULTI) { | ||
1136 | switch (use_dst_type) { | ||
1137 | case DST_TYPE_IS_SAT: | ||
1138 | /* STV0299 check */ | ||
1139 | if (dst_check_stv0299(state) < 0) { | ||
1140 | dprintk(verbose, DST_ERROR, 1, "Unsupported"); | ||
1141 | state->tuner_type = TUNER_TYPE_MB86A15; | ||
1142 | } | ||
1143 | break; | ||
1144 | default: | ||
1145 | break; | ||
1146 | } | ||
1147 | if (dst_check_mb86a15(state) < 0) | ||
1148 | dprintk(verbose, DST_ERROR, 1, "Unsupported"); | ||
1149 | /* Single tuner */ | ||
1150 | } else { | ||
1151 | state->tuner_type = p_dst_type->tuner_type; | ||
1152 | } | ||
1153 | for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) { | ||
1154 | if (!(strncmp(p_dst_type->device_id, p_tuner_list->fw_name, 7)) && | ||
1155 | p_tuner_list->tuner_type == state->tuner_type) { | ||
1156 | dprintk(verbose, DST_ERROR, 1, "[%s] has a [%s]", | ||
1157 | p_dst_type->device_id, p_tuner_list->tuner_name); | ||
1158 | } | ||
1159 | } | ||
893 | break; | 1160 | break; |
894 | } | 1161 | } |
895 | } | 1162 | } |
@@ -900,10 +1167,10 @@ static int dst_get_device_id(struct dst_state *state) | |||
900 | use_dst_type = DST_TYPE_IS_SAT; | 1167 | use_dst_type = DST_TYPE_IS_SAT; |
901 | use_type_flags = DST_TYPE_HAS_SYMDIV; | 1168 | use_type_flags = DST_TYPE_HAS_SYMDIV; |
902 | } | 1169 | } |
903 | dst_type_print(use_dst_type); | 1170 | dst_type_print(state, use_dst_type); |
904 | state->type_flags = use_type_flags; | 1171 | state->type_flags = use_type_flags; |
905 | state->dst_type = use_dst_type; | 1172 | state->dst_type = use_dst_type; |
906 | dst_type_flags_print(state->type_flags); | 1173 | dst_type_flags_print(state); |
907 | 1174 | ||
908 | return 0; | 1175 | return 0; |
909 | } | 1176 | } |
@@ -911,15 +1178,15 @@ static int dst_get_device_id(struct dst_state *state) | |||
911 | static int dst_probe(struct dst_state *state) | 1178 | static int dst_probe(struct dst_state *state) |
912 | { | 1179 | { |
913 | mutex_init(&state->dst_mutex); | 1180 | mutex_init(&state->dst_mutex); |
914 | if ((rdc_8820_reset(state)) < 0) { | 1181 | if (dst_addons & DST_TYPE_HAS_CA) { |
915 | dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed."); | 1182 | if ((rdc_8820_reset(state)) < 0) { |
916 | return -1; | 1183 | dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed."); |
917 | } | 1184 | return -1; |
918 | if (dst_addons & DST_TYPE_HAS_CA) | 1185 | } |
919 | msleep(4000); | 1186 | msleep(4000); |
920 | else | 1187 | } else { |
921 | msleep(100); | 1188 | msleep(100); |
922 | 1189 | } | |
923 | if ((dst_comm_init(state)) < 0) { | 1190 | if ((dst_comm_init(state)) < 0) { |
924 | dprintk(verbose, DST_ERROR, 1, "DST Initialization Failed."); | 1191 | dprintk(verbose, DST_ERROR, 1, "DST Initialization Failed."); |
925 | return -1; | 1192 | return -1; |
@@ -931,7 +1198,6 @@ static int dst_probe(struct dst_state *state) | |||
931 | } | 1198 | } |
932 | if (dst_get_mac(state) < 0) { | 1199 | if (dst_get_mac(state) < 0) { |
933 | dprintk(verbose, DST_INFO, 1, "MAC: Unsupported command"); | 1200 | dprintk(verbose, DST_INFO, 1, "MAC: Unsupported command"); |
934 | return 0; | ||
935 | } | 1201 | } |
936 | if ((state->type_flags & DST_TYPE_HAS_MULTI_FE) || (state->type_flags & DST_TYPE_HAS_FW_BUILD)) { | 1202 | if ((state->type_flags & DST_TYPE_HAS_MULTI_FE) || (state->type_flags & DST_TYPE_HAS_FW_BUILD)) { |
937 | if (dst_get_tuner_info(state) < 0) | 1203 | if (dst_get_tuner_info(state) < 0) |
@@ -1048,6 +1314,10 @@ static int dst_get_signal(struct dst_state *state) | |||
1048 | state->decode_lock = (state->rxbuffer[1]) ? 1 : 0; | 1314 | state->decode_lock = (state->rxbuffer[1]) ? 1 : 0; |
1049 | state->decode_strength = state->rxbuffer[4] << 8; | 1315 | state->decode_strength = state->rxbuffer[4] << 8; |
1050 | state->decode_snr = state->rxbuffer[3] << 8; | 1316 | state->decode_snr = state->rxbuffer[3] << 8; |
1317 | } else if (state->dst_type == DST_TYPE_IS_ATSC) { | ||
1318 | state->decode_lock = (state->rxbuffer[6] == 0x00) ? 1 : 0; | ||
1319 | state->decode_strength = state->rxbuffer[4] << 8; | ||
1320 | state->decode_snr = state->rxbuffer[2] << 8 | state->rxbuffer[3]; | ||
1051 | } | 1321 | } |
1052 | state->cur_jiff = jiffies; | 1322 | state->cur_jiff = jiffies; |
1053 | } | 1323 | } |
@@ -1078,8 +1348,9 @@ static int dst_get_tuna(struct dst_state *state) | |||
1078 | state->diseq_flags &= ~(HAS_LOCK); | 1348 | state->diseq_flags &= ~(HAS_LOCK); |
1079 | if (!dst_wait_dst_ready(state, NO_DELAY)) | 1349 | if (!dst_wait_dst_ready(state, NO_DELAY)) |
1080 | return -EIO; | 1350 | return -EIO; |
1081 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) | 1351 | if ((state->type_flags & DST_TYPE_HAS_VLF) && |
1082 | /* how to get variable length reply ???? */ | 1352 | !(state->dst_type == DST_TYPE_IS_ATSC)) |
1353 | |||
1083 | retval = read_dst(state, state->rx_tuna, 10); | 1354 | retval = read_dst(state, state->rx_tuna, 10); |
1084 | else | 1355 | else |
1085 | retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM); | 1356 | retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM); |
@@ -1087,7 +1358,10 @@ static int dst_get_tuna(struct dst_state *state) | |||
1087 | dprintk(verbose, DST_DEBUG, 1, "read not successful"); | 1358 | dprintk(verbose, DST_DEBUG, 1, "read not successful"); |
1088 | return retval; | 1359 | return retval; |
1089 | } | 1360 | } |
1090 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { | 1361 | if ((state->type_flags & DST_TYPE_HAS_VLF) && |
1362 | !(state->dst_type == DST_TYPE_IS_CABLE) && | ||
1363 | !(state->dst_type == DST_TYPE_IS_ATSC)) { | ||
1364 | |||
1091 | if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) { | 1365 | if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) { |
1092 | dprintk(verbose, DST_INFO, 1, "checksum failure ? "); | 1366 | dprintk(verbose, DST_INFO, 1, "checksum failure ? "); |
1093 | return -EIO; | 1367 | return -EIO; |
@@ -1133,7 +1407,10 @@ static int dst_write_tuna(struct dvb_frontend *fe) | |||
1133 | dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed."); | 1407 | dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed."); |
1134 | goto error; | 1408 | goto error; |
1135 | } | 1409 | } |
1136 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { | 1410 | // if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { |
1411 | if ((state->type_flags & DST_TYPE_HAS_VLF) && | ||
1412 | (!(state->dst_type == DST_TYPE_IS_ATSC))) { | ||
1413 | |||
1137 | state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9); | 1414 | state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9); |
1138 | retval = write_dst(state, &state->tx_tuna[0], 10); | 1415 | retval = write_dst(state, &state->tx_tuna[0], 10); |
1139 | } else { | 1416 | } else { |
@@ -1189,9 +1466,12 @@ static int dst_set_diseqc(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd | |||
1189 | 1466 | ||
1190 | if (state->dst_type != DST_TYPE_IS_SAT) | 1467 | if (state->dst_type != DST_TYPE_IS_SAT) |
1191 | return 0; | 1468 | return 0; |
1192 | if (cmd->msg_len == 0 || cmd->msg_len > 4) | 1469 | if (cmd->msg_len > 0 && cmd->msg_len < 5) |
1470 | memcpy(&paket[3], cmd->msg, cmd->msg_len); | ||
1471 | else if (cmd->msg_len == 5 && state->dst_hw_cap & DST_TYPE_HAS_DISEQC5) | ||
1472 | memcpy(&paket[2], cmd->msg, cmd->msg_len); | ||
1473 | else | ||
1193 | return -EINVAL; | 1474 | return -EINVAL; |
1194 | memcpy(&paket[3], cmd->msg, cmd->msg_len); | ||
1195 | paket[7] = dst_check_sum(&paket[0], 7); | 1475 | paket[7] = dst_check_sum(&paket[0], 7); |
1196 | dst_command(state, paket, 8); | 1476 | dst_command(state, paket, 8); |
1197 | return 0; | 1477 | return 0; |
@@ -1287,8 +1567,9 @@ static int dst_init(struct dvb_frontend *fe) | |||
1287 | static u8 sat_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x55, 0xbd, 0x50, 0x00, 0x00 }; | 1567 | static u8 sat_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x55, 0xbd, 0x50, 0x00, 0x00 }; |
1288 | static u8 ter_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; | 1568 | static u8 ter_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; |
1289 | static u8 ter_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; | 1569 | static u8 ter_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; |
1290 | static u8 cab_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; | ||
1291 | static u8 cab_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; | 1570 | static u8 cab_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; |
1571 | static u8 cab_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; | ||
1572 | static u8 atsc_tuner[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; | ||
1292 | 1573 | ||
1293 | state->inversion = INVERSION_OFF; | 1574 | state->inversion = INVERSION_OFF; |
1294 | state->voltage = SEC_VOLTAGE_13; | 1575 | state->voltage = SEC_VOLTAGE_13; |
@@ -1298,11 +1579,13 @@ static int dst_init(struct dvb_frontend *fe) | |||
1298 | state->bandwidth = BANDWIDTH_7_MHZ; | 1579 | state->bandwidth = BANDWIDTH_7_MHZ; |
1299 | state->cur_jiff = jiffies; | 1580 | state->cur_jiff = jiffies; |
1300 | if (state->dst_type == DST_TYPE_IS_SAT) | 1581 | if (state->dst_type == DST_TYPE_IS_SAT) |
1301 | memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? sat_tuna_188 : sat_tuna_204), sizeof (sat_tuna_204)); | 1582 | memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? sat_tuna_188 : sat_tuna_204), sizeof (sat_tuna_204)); |
1302 | else if (state->dst_type == DST_TYPE_IS_TERR) | 1583 | else if (state->dst_type == DST_TYPE_IS_TERR) |
1303 | memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? ter_tuna_188 : ter_tuna_204), sizeof (ter_tuna_204)); | 1584 | memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? ter_tuna_188 : ter_tuna_204), sizeof (ter_tuna_204)); |
1304 | else if (state->dst_type == DST_TYPE_IS_CABLE) | 1585 | else if (state->dst_type == DST_TYPE_IS_CABLE) |
1305 | memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_NEWTUNE) ? cab_tuna_188 : cab_tuna_204), sizeof (cab_tuna_204)); | 1586 | memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? cab_tuna_188 : cab_tuna_204), sizeof (cab_tuna_204)); |
1587 | else if (state->dst_type == DST_TYPE_IS_ATSC) | ||
1588 | memcpy(state->tx_tuna, atsc_tuner, sizeof (atsc_tuner)); | ||
1306 | 1589 | ||
1307 | return 0; | 1590 | return 0; |
1308 | } | 1591 | } |
@@ -1341,7 +1624,36 @@ static int dst_read_snr(struct dvb_frontend *fe, u16 *snr) | |||
1341 | return 0; | 1624 | return 0; |
1342 | } | 1625 | } |
1343 | 1626 | ||
1344 | static int dst_set_frontend(struct dvb_frontend* fe, | 1627 | static int dst_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) |
1628 | { | ||
1629 | struct dst_state *state = fe->demodulator_priv; | ||
1630 | |||
1631 | if (p != NULL) { | ||
1632 | dst_set_freq(state, p->frequency); | ||
1633 | dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency); | ||
1634 | |||
1635 | if (state->dst_type == DST_TYPE_IS_SAT) { | ||
1636 | if (state->type_flags & DST_TYPE_HAS_OBS_REGS) | ||
1637 | dst_set_inversion(state, p->inversion); | ||
1638 | dst_set_fec(state, p->u.qpsk.fec_inner); | ||
1639 | dst_set_symbolrate(state, p->u.qpsk.symbol_rate); | ||
1640 | dst_set_polarization(state); | ||
1641 | dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->u.qpsk.symbol_rate); | ||
1642 | |||
1643 | } else if (state->dst_type == DST_TYPE_IS_TERR) | ||
1644 | dst_set_bandwidth(state, p->u.ofdm.bandwidth); | ||
1645 | else if (state->dst_type == DST_TYPE_IS_CABLE) { | ||
1646 | dst_set_fec(state, p->u.qam.fec_inner); | ||
1647 | dst_set_symbolrate(state, p->u.qam.symbol_rate); | ||
1648 | dst_set_modulation(state, p->u.qam.modulation); | ||
1649 | } | ||
1650 | dst_write_tuna(fe); | ||
1651 | } | ||
1652 | |||
1653 | return 0; | ||
1654 | } | ||
1655 | |||
1656 | static int dst_tune_frontend(struct dvb_frontend* fe, | ||
1345 | struct dvb_frontend_parameters* p, | 1657 | struct dvb_frontend_parameters* p, |
1346 | unsigned int mode_flags, | 1658 | unsigned int mode_flags, |
1347 | int *delay, | 1659 | int *delay, |
@@ -1378,6 +1690,11 @@ static int dst_set_frontend(struct dvb_frontend* fe, | |||
1378 | return 0; | 1690 | return 0; |
1379 | } | 1691 | } |
1380 | 1692 | ||
1693 | static int dst_get_tuning_algo(struct dvb_frontend *fe) | ||
1694 | { | ||
1695 | return dst_algo; | ||
1696 | } | ||
1697 | |||
1381 | static int dst_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) | 1698 | static int dst_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) |
1382 | { | 1699 | { |
1383 | struct dst_state *state = fe->demodulator_priv; | 1700 | struct dst_state *state = fe->demodulator_priv; |
@@ -1408,6 +1725,7 @@ static void dst_release(struct dvb_frontend *fe) | |||
1408 | static struct dvb_frontend_ops dst_dvbt_ops; | 1725 | static struct dvb_frontend_ops dst_dvbt_ops; |
1409 | static struct dvb_frontend_ops dst_dvbs_ops; | 1726 | static struct dvb_frontend_ops dst_dvbs_ops; |
1410 | static struct dvb_frontend_ops dst_dvbc_ops; | 1727 | static struct dvb_frontend_ops dst_dvbc_ops; |
1728 | static struct dvb_frontend_ops dst_atsc_ops; | ||
1411 | 1729 | ||
1412 | struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter) | 1730 | struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter) |
1413 | { | 1731 | { |
@@ -1417,24 +1735,25 @@ struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_ad | |||
1417 | return NULL; | 1735 | return NULL; |
1418 | } | 1736 | } |
1419 | /* determine settings based on type */ | 1737 | /* determine settings based on type */ |
1738 | /* create dvb_frontend */ | ||
1420 | switch (state->dst_type) { | 1739 | switch (state->dst_type) { |
1421 | case DST_TYPE_IS_TERR: | 1740 | case DST_TYPE_IS_TERR: |
1422 | memcpy(&state->ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops)); | 1741 | memcpy(&state->frontend.ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops)); |
1423 | break; | 1742 | break; |
1424 | case DST_TYPE_IS_CABLE: | 1743 | case DST_TYPE_IS_CABLE: |
1425 | memcpy(&state->ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops)); | 1744 | memcpy(&state->frontend.ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops)); |
1426 | break; | 1745 | break; |
1427 | case DST_TYPE_IS_SAT: | 1746 | case DST_TYPE_IS_SAT: |
1428 | memcpy(&state->ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops)); | 1747 | memcpy(&state->frontend.ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops)); |
1748 | break; | ||
1749 | case DST_TYPE_IS_ATSC: | ||
1750 | memcpy(&state->frontend.ops, &dst_atsc_ops, sizeof(struct dvb_frontend_ops)); | ||
1429 | break; | 1751 | break; |
1430 | default: | 1752 | default: |
1431 | dprintk(verbose, DST_ERROR, 1, "unknown DST type. please report to the LinuxTV.org DVB mailinglist."); | 1753 | dprintk(verbose, DST_ERROR, 1, "unknown DST type. please report to the LinuxTV.org DVB mailinglist."); |
1432 | kfree(state); | 1754 | kfree(state); |
1433 | return NULL; | 1755 | return NULL; |
1434 | } | 1756 | } |
1435 | |||
1436 | /* create dvb_frontend */ | ||
1437 | state->frontend.ops = &state->ops; | ||
1438 | state->frontend.demodulator_priv = state; | 1757 | state->frontend.demodulator_priv = state; |
1439 | 1758 | ||
1440 | return state; /* Manu (DST is a card not a frontend) */ | 1759 | return state; /* Manu (DST is a card not a frontend) */ |
@@ -1455,8 +1774,10 @@ static struct dvb_frontend_ops dst_dvbt_ops = { | |||
1455 | 1774 | ||
1456 | .release = dst_release, | 1775 | .release = dst_release, |
1457 | .init = dst_init, | 1776 | .init = dst_init, |
1458 | .tune = dst_set_frontend, | 1777 | .tune = dst_tune_frontend, |
1778 | .set_frontend = dst_set_frontend, | ||
1459 | .get_frontend = dst_get_frontend, | 1779 | .get_frontend = dst_get_frontend, |
1780 | .get_frontend_algo = dst_get_tuning_algo, | ||
1460 | .read_status = dst_read_status, | 1781 | .read_status = dst_read_status, |
1461 | .read_signal_strength = dst_read_signal_strength, | 1782 | .read_signal_strength = dst_read_signal_strength, |
1462 | .read_snr = dst_read_snr, | 1783 | .read_snr = dst_read_snr, |
@@ -1479,8 +1800,10 @@ static struct dvb_frontend_ops dst_dvbs_ops = { | |||
1479 | 1800 | ||
1480 | .release = dst_release, | 1801 | .release = dst_release, |
1481 | .init = dst_init, | 1802 | .init = dst_init, |
1482 | .tune = dst_set_frontend, | 1803 | .tune = dst_tune_frontend, |
1804 | .set_frontend = dst_set_frontend, | ||
1483 | .get_frontend = dst_get_frontend, | 1805 | .get_frontend = dst_get_frontend, |
1806 | .get_frontend_algo = dst_get_tuning_algo, | ||
1484 | .read_status = dst_read_status, | 1807 | .read_status = dst_read_status, |
1485 | .read_signal_strength = dst_read_signal_strength, | 1808 | .read_signal_strength = dst_read_signal_strength, |
1486 | .read_snr = dst_read_snr, | 1809 | .read_snr = dst_read_snr, |
@@ -1506,13 +1829,38 @@ static struct dvb_frontend_ops dst_dvbc_ops = { | |||
1506 | 1829 | ||
1507 | .release = dst_release, | 1830 | .release = dst_release, |
1508 | .init = dst_init, | 1831 | .init = dst_init, |
1509 | .tune = dst_set_frontend, | 1832 | .tune = dst_tune_frontend, |
1833 | .set_frontend = dst_set_frontend, | ||
1834 | .get_frontend = dst_get_frontend, | ||
1835 | .get_frontend_algo = dst_get_tuning_algo, | ||
1836 | .read_status = dst_read_status, | ||
1837 | .read_signal_strength = dst_read_signal_strength, | ||
1838 | .read_snr = dst_read_snr, | ||
1839 | }; | ||
1840 | |||
1841 | static struct dvb_frontend_ops dst_atsc_ops = { | ||
1842 | .info = { | ||
1843 | .name = "DST ATSC", | ||
1844 | .type = FE_ATSC, | ||
1845 | .frequency_stepsize = 62500, | ||
1846 | .frequency_min = 510000000, | ||
1847 | .frequency_max = 858000000, | ||
1848 | .symbol_rate_min = 1000000, | ||
1849 | .symbol_rate_max = 45000000, | ||
1850 | .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO | FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB | ||
1851 | }, | ||
1852 | |||
1853 | .release = dst_release, | ||
1854 | .init = dst_init, | ||
1855 | .tune = dst_tune_frontend, | ||
1856 | .set_frontend = dst_set_frontend, | ||
1510 | .get_frontend = dst_get_frontend, | 1857 | .get_frontend = dst_get_frontend, |
1858 | .get_frontend_algo = dst_get_tuning_algo, | ||
1511 | .read_status = dst_read_status, | 1859 | .read_status = dst_read_status, |
1512 | .read_signal_strength = dst_read_signal_strength, | 1860 | .read_signal_strength = dst_read_signal_strength, |
1513 | .read_snr = dst_read_snr, | 1861 | .read_snr = dst_read_snr, |
1514 | }; | 1862 | }; |
1515 | 1863 | ||
1516 | MODULE_DESCRIPTION("DST DVB-S/T/C Combo Frontend driver"); | 1864 | MODULE_DESCRIPTION("DST DVB-S/T/C/ATSC Combo Frontend driver"); |
1517 | MODULE_AUTHOR("Jamie Honan, Manu Abraham"); | 1865 | MODULE_AUTHOR("Jamie Honan, Manu Abraham"); |
1518 | MODULE_LICENSE("GPL"); | 1866 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c index f6b49a801eba..fa923b9b346e 100644 --- a/drivers/media/dvb/bt8xx/dst_ca.c +++ b/drivers/media/dvb/bt8xx/dst_ca.c | |||
@@ -68,6 +68,13 @@ static int ca_set_pid(void) | |||
68 | return -EOPNOTSUPP; | 68 | return -EOPNOTSUPP; |
69 | } | 69 | } |
70 | 70 | ||
71 | static void put_command_and_length(u8 *data, int command, int length) | ||
72 | { | ||
73 | data[0] = (command >> 16) & 0xff; | ||
74 | data[1] = (command >> 8) & 0xff; | ||
75 | data[2] = command & 0xff; | ||
76 | data[3] = length; | ||
77 | } | ||
71 | 78 | ||
72 | static void put_checksum(u8 *check_string, int length) | 79 | static void put_checksum(u8 *check_string, int length) |
73 | { | 80 | { |
@@ -124,15 +131,18 @@ static int dst_put_ci(struct dst_state *state, u8 *data, int len, u8 *ca_string, | |||
124 | u8 dst_ca_comm_err = 0; | 131 | u8 dst_ca_comm_err = 0; |
125 | 132 | ||
126 | while (dst_ca_comm_err < RETRIES) { | 133 | while (dst_ca_comm_err < RETRIES) { |
127 | dst_comm_init(state); | ||
128 | dprintk(verbose, DST_CA_NOTICE, 1, " Put Command"); | 134 | dprintk(verbose, DST_CA_NOTICE, 1, " Put Command"); |
129 | if (dst_ci_command(state, data, ca_string, len, read)) { // If error | 135 | if (dst_ci_command(state, data, ca_string, len, read)) { // If error |
130 | dst_error_recovery(state); | 136 | dst_error_recovery(state); |
131 | dst_ca_comm_err++; // work required here. | 137 | dst_ca_comm_err++; // work required here. |
138 | } else { | ||
139 | break; | ||
132 | } | 140 | } |
133 | break; | ||
134 | } | 141 | } |
135 | 142 | ||
143 | if(dst_ca_comm_err == RETRIES) | ||
144 | return -1; | ||
145 | |||
136 | return 0; | 146 | return 0; |
137 | } | 147 | } |
138 | 148 | ||
@@ -140,6 +150,7 @@ static int dst_put_ci(struct dst_state *state, u8 *data, int len, u8 *ca_string, | |||
140 | 150 | ||
141 | static int ca_get_app_info(struct dst_state *state) | 151 | static int ca_get_app_info(struct dst_state *state) |
142 | { | 152 | { |
153 | int length, str_length; | ||
143 | static u8 command[8] = {0x07, 0x40, 0x01, 0x00, 0x01, 0x00, 0x00, 0xff}; | 154 | static u8 command[8] = {0x07, 0x40, 0x01, 0x00, 0x01, 0x00, 0x00, 0xff}; |
144 | 155 | ||
145 | put_checksum(&command[0], command[0]); | 156 | put_checksum(&command[0], command[0]); |
@@ -154,6 +165,68 @@ static int ca_get_app_info(struct dst_state *state) | |||
154 | (state->messages[10] << 8) | state->messages[11], __FUNCTION__, (char *)(&state->messages[12])); | 165 | (state->messages[10] << 8) | state->messages[11], __FUNCTION__, (char *)(&state->messages[12])); |
155 | dprintk(verbose, DST_CA_INFO, 1, " =================================================================================================="); | 166 | dprintk(verbose, DST_CA_INFO, 1, " =================================================================================================="); |
156 | 167 | ||
168 | // Transform dst message to correct application_info message | ||
169 | length = state->messages[5]; | ||
170 | str_length = length - 6; | ||
171 | if (str_length < 0) { | ||
172 | str_length = 0; | ||
173 | dprintk(verbose, DST_CA_ERROR, 1, "Invalid string length returned in ca_get_app_info(). Recovering."); | ||
174 | } | ||
175 | |||
176 | // First, the command and length fields | ||
177 | put_command_and_length(&state->messages[0], CA_APP_INFO, length); | ||
178 | |||
179 | // Copy application_type, application_manufacturer and manufacturer_code | ||
180 | memcpy(&state->messages[4], &state->messages[7], 5); | ||
181 | |||
182 | // Set string length and copy string | ||
183 | state->messages[9] = str_length; | ||
184 | memcpy(&state->messages[10], &state->messages[12], str_length); | ||
185 | |||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | static int ca_get_ca_info(struct dst_state *state) | ||
190 | { | ||
191 | int srcPtr, dstPtr, i, num_ids; | ||
192 | static u8 slot_command[8] = {0x07, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0xff}; | ||
193 | const int in_system_id_pos = 8, out_system_id_pos = 4, in_num_ids_pos = 7; | ||
194 | |||
195 | put_checksum(&slot_command[0], slot_command[0]); | ||
196 | if ((dst_put_ci(state, slot_command, sizeof (slot_command), state->messages, GET_REPLY)) < 0) { | ||
197 | dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !"); | ||
198 | return -1; | ||
199 | } | ||
200 | dprintk(verbose, DST_CA_INFO, 1, " -->dst_put_ci SUCCESS !"); | ||
201 | |||
202 | // Print raw data | ||
203 | dprintk(verbose, DST_CA_INFO, 0, " DST data = ["); | ||
204 | for (i = 0; i < state->messages[0] + 1; i++) { | ||
205 | dprintk(verbose, DST_CA_INFO, 0, " 0x%02x", state->messages[i]); | ||
206 | } | ||
207 | dprintk(verbose, DST_CA_INFO, 0, "]\n"); | ||
208 | |||
209 | // Set the command and length of the output | ||
210 | num_ids = state->messages[in_num_ids_pos]; | ||
211 | if (num_ids >= 100) { | ||
212 | num_ids = 100; | ||
213 | dprintk(verbose, DST_CA_ERROR, 1, "Invalid number of ids (>100). Recovering."); | ||
214 | } | ||
215 | put_command_and_length(&state->messages[0], CA_INFO, num_ids * 2); | ||
216 | |||
217 | dprintk(verbose, DST_CA_INFO, 0, " CA_INFO = ["); | ||
218 | srcPtr = in_system_id_pos; | ||
219 | dstPtr = out_system_id_pos; | ||
220 | for(i = 0; i < num_ids; i++) { | ||
221 | dprintk(verbose, DST_CA_INFO, 0, " 0x%02x%02x", state->messages[srcPtr + 0], state->messages[srcPtr + 1]); | ||
222 | // Append to output | ||
223 | state->messages[dstPtr + 0] = state->messages[srcPtr + 0]; | ||
224 | state->messages[dstPtr + 1] = state->messages[srcPtr + 1]; | ||
225 | srcPtr += 2; | ||
226 | dstPtr += 2; | ||
227 | } | ||
228 | dprintk(verbose, DST_CA_INFO, 0, "]\n"); | ||
229 | |||
157 | return 0; | 230 | return 0; |
158 | } | 231 | } |
159 | 232 | ||
@@ -174,7 +247,7 @@ static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps, | |||
174 | 247 | ||
175 | dprintk(verbose, DST_CA_INFO, 1, " Slot cap = [%d]", slot_cap[7]); | 248 | dprintk(verbose, DST_CA_INFO, 1, " Slot cap = [%d]", slot_cap[7]); |
176 | dprintk(verbose, DST_CA_INFO, 0, "===================================\n"); | 249 | dprintk(verbose, DST_CA_INFO, 0, "===================================\n"); |
177 | for (i = 0; i < 8; i++) | 250 | for (i = 0; i < slot_cap[0] + 1; i++) |
178 | dprintk(verbose, DST_CA_INFO, 0, " %d", slot_cap[i]); | 251 | dprintk(verbose, DST_CA_INFO, 0, " %d", slot_cap[i]); |
179 | dprintk(verbose, DST_CA_INFO, 0, "\n"); | 252 | dprintk(verbose, DST_CA_INFO, 0, "\n"); |
180 | 253 | ||
@@ -260,6 +333,11 @@ static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, | |||
260 | if (copy_to_user(arg, p_ca_message, sizeof (struct ca_msg)) ) | 333 | if (copy_to_user(arg, p_ca_message, sizeof (struct ca_msg)) ) |
261 | return -EFAULT; | 334 | return -EFAULT; |
262 | break; | 335 | break; |
336 | case CA_INFO: | ||
337 | memcpy(p_ca_message->msg, state->messages, 128); | ||
338 | if (copy_to_user(arg, p_ca_message, sizeof (struct ca_msg)) ) | ||
339 | return -EFAULT; | ||
340 | break; | ||
263 | } | 341 | } |
264 | } | 342 | } |
265 | 343 | ||
@@ -302,7 +380,7 @@ static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 l | |||
302 | rdc_reset_state(state); | 380 | rdc_reset_state(state); |
303 | return -1; | 381 | return -1; |
304 | } | 382 | } |
305 | dprintk(verbose, DST_CA_NOTICE, 1, " DST-CI Command succes."); | 383 | dprintk(verbose, DST_CA_NOTICE, 1, " DST-CI Command success."); |
306 | 384 | ||
307 | return 0; | 385 | return 0; |
308 | } | 386 | } |
@@ -340,6 +418,7 @@ static int debug_string(u8 *msg, u32 length, u32 offset) | |||
340 | return 0; | 418 | return 0; |
341 | } | 419 | } |
342 | 420 | ||
421 | |||
343 | static int ca_set_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u8 reply, u8 query) | 422 | static int ca_set_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u8 reply, u8 query) |
344 | { | 423 | { |
345 | u32 length = 0; | 424 | u32 length = 0; |
@@ -455,6 +534,16 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, | |||
455 | } | 534 | } |
456 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_APP_INFO_ENQUIRY Success !"); | 535 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_APP_INFO_ENQUIRY Success !"); |
457 | break; | 536 | break; |
537 | case CA_INFO_ENQUIRY: | ||
538 | dprintk(verbose, DST_CA_INFO, 1, " Getting CA Information"); | ||
539 | |||
540 | if ((ca_get_ca_info(state)) < 0) { | ||
541 | dprintk(verbose, DST_CA_ERROR, 1, " -->CA_INFO_ENQUIRY Failed !"); | ||
542 | result = -1; | ||
543 | goto free_mem_and_exit; | ||
544 | } | ||
545 | dprintk(verbose, DST_CA_INFO, 1, " -->CA_INFO_ENQUIRY Success !"); | ||
546 | break; | ||
458 | } | 547 | } |
459 | } | 548 | } |
460 | free_mem_and_exit: | 549 | free_mem_and_exit: |
@@ -473,18 +562,15 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
473 | void __user *arg = (void __user *)ioctl_arg; | 562 | void __user *arg = (void __user *)ioctl_arg; |
474 | int result = 0; | 563 | int result = 0; |
475 | 564 | ||
476 | if ((p_ca_message = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) { | 565 | p_ca_message = kmalloc(sizeof (struct ca_msg), GFP_KERNEL); |
477 | dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure"); | 566 | p_ca_slot_info = kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL); |
478 | return -ENOMEM; | 567 | p_ca_caps = kmalloc(sizeof (struct ca_caps), GFP_KERNEL); |
479 | } | 568 | if (!p_ca_message || !p_ca_slot_info || !p_ca_caps) { |
480 | if ((p_ca_slot_info = (struct ca_slot_info *) kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL)) == NULL) { | ||
481 | dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure"); | 569 | dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure"); |
482 | return -ENOMEM; | 570 | result = -ENOMEM; |
483 | } | 571 | goto free_mem_and_exit; |
484 | if ((p_ca_caps = (struct ca_caps *) kmalloc(sizeof (struct ca_caps), GFP_KERNEL)) == NULL) { | ||
485 | dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure"); | ||
486 | return -ENOMEM; | ||
487 | } | 572 | } |
573 | |||
488 | /* We have now only the standard ioctl's, the driver is upposed to handle internals. */ | 574 | /* We have now only the standard ioctl's, the driver is upposed to handle internals. */ |
489 | switch (cmd) { | 575 | switch (cmd) { |
490 | case CA_SEND_MSG: | 576 | case CA_SEND_MSG: |
@@ -582,7 +668,7 @@ static int dst_ca_release(struct inode *inode, struct file *file) | |||
582 | 668 | ||
583 | static ssize_t dst_ca_read(struct file *file, char __user *buffer, size_t length, loff_t *offset) | 669 | static ssize_t dst_ca_read(struct file *file, char __user *buffer, size_t length, loff_t *offset) |
584 | { | 670 | { |
585 | int bytes_read = 0; | 671 | ssize_t bytes_read = 0; |
586 | 672 | ||
587 | dprintk(verbose, DST_CA_DEBUG, 1, " Device read."); | 673 | dprintk(verbose, DST_CA_DEBUG, 1, " Device read."); |
588 | 674 | ||
diff --git a/drivers/media/dvb/bt8xx/dst_common.h b/drivers/media/dvb/bt8xx/dst_common.h index 51d4e043716c..0677b047b3a7 100644 --- a/drivers/media/dvb/bt8xx/dst_common.h +++ b/drivers/media/dvb/bt8xx/dst_common.h | |||
@@ -42,7 +42,7 @@ | |||
42 | #define DST_TYPE_IS_CABLE 2 | 42 | #define DST_TYPE_IS_CABLE 2 |
43 | #define DST_TYPE_IS_ATSC 3 | 43 | #define DST_TYPE_IS_ATSC 3 |
44 | 44 | ||
45 | #define DST_TYPE_HAS_NEWTUNE 1 | 45 | #define DST_TYPE_HAS_TS188 1 |
46 | #define DST_TYPE_HAS_TS204 2 | 46 | #define DST_TYPE_HAS_TS204 2 |
47 | #define DST_TYPE_HAS_SYMDIV 4 | 47 | #define DST_TYPE_HAS_SYMDIV 4 |
48 | #define DST_TYPE_HAS_FW_1 8 | 48 | #define DST_TYPE_HAS_FW_1 8 |
@@ -52,6 +52,9 @@ | |||
52 | #define DST_TYPE_HAS_OBS_REGS 128 | 52 | #define DST_TYPE_HAS_OBS_REGS 128 |
53 | #define DST_TYPE_HAS_INC_COUNT 256 | 53 | #define DST_TYPE_HAS_INC_COUNT 256 |
54 | #define DST_TYPE_HAS_MULTI_FE 512 | 54 | #define DST_TYPE_HAS_MULTI_FE 512 |
55 | #define DST_TYPE_HAS_NEWTUNE_2 1024 | ||
56 | #define DST_TYPE_HAS_DBOARD 2048 | ||
57 | #define DST_TYPE_HAS_VLF 4096 | ||
55 | 58 | ||
56 | /* Card capability list */ | 59 | /* Card capability list */ |
57 | 60 | ||
@@ -64,6 +67,20 @@ | |||
64 | #define DST_TYPE_HAS_ANALOG 64 /* Analog inputs */ | 67 | #define DST_TYPE_HAS_ANALOG 64 /* Analog inputs */ |
65 | #define DST_TYPE_HAS_SESSION 128 | 68 | #define DST_TYPE_HAS_SESSION 128 |
66 | 69 | ||
70 | #define TUNER_TYPE_MULTI 1 | ||
71 | #define TUNER_TYPE_UNKNOWN 2 | ||
72 | /* DVB-S */ | ||
73 | #define TUNER_TYPE_L64724 4 | ||
74 | #define TUNER_TYPE_STV0299 8 | ||
75 | #define TUNER_TYPE_MB86A15 16 | ||
76 | |||
77 | /* DVB-T */ | ||
78 | #define TUNER_TYPE_TDA10046 32 | ||
79 | |||
80 | /* ATSC */ | ||
81 | #define TUNER_TYPE_NXT200x 64 | ||
82 | |||
83 | |||
67 | #define RDC_8820_PIO_0_DISABLE 0 | 84 | #define RDC_8820_PIO_0_DISABLE 0 |
68 | #define RDC_8820_PIO_0_ENABLE 1 | 85 | #define RDC_8820_PIO_0_ENABLE 1 |
69 | #define RDC_8820_INT 2 | 86 | #define RDC_8820_INT 2 |
@@ -84,8 +101,6 @@ struct dst_state { | |||
84 | 101 | ||
85 | struct bt878* bt; | 102 | struct bt878* bt; |
86 | 103 | ||
87 | struct dvb_frontend_ops ops; | ||
88 | |||
89 | /* configuration settings */ | 104 | /* configuration settings */ |
90 | const struct dst_config* config; | 105 | const struct dst_config* config; |
91 | 106 | ||
@@ -121,8 +136,17 @@ struct dst_state { | |||
121 | u8 card_info[8]; | 136 | u8 card_info[8]; |
122 | u8 vendor[8]; | 137 | u8 vendor[8]; |
123 | u8 board_info[8]; | 138 | u8 board_info[8]; |
124 | 139 | u32 tuner_type; | |
140 | char *tuner_name; | ||
125 | struct mutex dst_mutex; | 141 | struct mutex dst_mutex; |
142 | u8 fw_name[8]; | ||
143 | }; | ||
144 | |||
145 | struct tuner_types { | ||
146 | u32 tuner_type; | ||
147 | char *tuner_name; | ||
148 | char *board_name; | ||
149 | char *fw_name; | ||
126 | }; | 150 | }; |
127 | 151 | ||
128 | struct dst_types { | 152 | struct dst_types { |
@@ -131,6 +155,7 @@ struct dst_types { | |||
131 | u8 dst_type; | 155 | u8 dst_type; |
132 | u32 type_flags; | 156 | u32 type_flags; |
133 | u32 dst_feature; | 157 | u32 dst_feature; |
158 | u32 tuner_type; | ||
134 | }; | 159 | }; |
135 | 160 | ||
136 | struct dst_config | 161 | struct dst_config |
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c index ccc7b2eb4a2d..b715b972d2fc 100644 --- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c +++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c | |||
@@ -147,12 +147,15 @@ static int thomson_dtt7579_demod_init(struct dvb_frontend* fe) | |||
147 | return 0; | 147 | return 0; |
148 | } | 148 | } |
149 | 149 | ||
150 | static int thomson_dtt7579_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf) | 150 | static int thomson_dtt7579_tuner_calc_regs(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf, int buf_len) |
151 | { | 151 | { |
152 | u32 div; | 152 | u32 div; |
153 | unsigned char bs = 0; | 153 | unsigned char bs = 0; |
154 | unsigned char cp = 0; | 154 | unsigned char cp = 0; |
155 | 155 | ||
156 | if (buf_len < 5) | ||
157 | return -EINVAL; | ||
158 | |||
156 | div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; | 159 | div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; |
157 | 160 | ||
158 | if (params->frequency < 542000000) | 161 | if (params->frequency < 542000000) |
@@ -169,22 +172,25 @@ static int thomson_dtt7579_pll_set(struct dvb_frontend* fe, struct dvb_frontend_ | |||
169 | else | 172 | else |
170 | bs = 0x08; | 173 | bs = 0x08; |
171 | 174 | ||
172 | pllbuf[0] = 0xc0; // Note: non-linux standard PLL i2c address | 175 | pllbuf[0] = 0x60; |
173 | pllbuf[1] = div >> 8; | 176 | pllbuf[1] = div >> 8; |
174 | pllbuf[2] = div & 0xff; | 177 | pllbuf[2] = div & 0xff; |
175 | pllbuf[3] = cp; | 178 | pllbuf[3] = cp; |
176 | pllbuf[4] = bs; | 179 | pllbuf[4] = bs; |
177 | 180 | ||
178 | return 0; | 181 | return 5; |
179 | } | 182 | } |
180 | 183 | ||
181 | static struct mt352_config thomson_dtt7579_config = { | 184 | static struct mt352_config thomson_dtt7579_config = { |
182 | .demod_address = 0x0f, | 185 | .demod_address = 0x0f, |
183 | .demod_init = thomson_dtt7579_demod_init, | 186 | .demod_init = thomson_dtt7579_demod_init, |
184 | .pll_set = thomson_dtt7579_pll_set, | ||
185 | }; | 187 | }; |
186 | 188 | ||
187 | static int cx24108_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 189 | static struct zl10353_config thomson_dtt7579_zl10353_config = { |
190 | .demod_address = 0x0f, | ||
191 | }; | ||
192 | |||
193 | static int cx24108_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | ||
188 | { | 194 | { |
189 | u32 freq = params->frequency; | 195 | u32 freq = params->frequency; |
190 | 196 | ||
@@ -237,7 +243,7 @@ static int cx24108_pll_set(struct dvb_frontend* fe, struct dvb_frontend_paramete | |||
237 | return 0; | 243 | return 0; |
238 | } | 244 | } |
239 | 245 | ||
240 | static int pinnsat_pll_init(struct dvb_frontend* fe) | 246 | static int pinnsat_tuner_init(struct dvb_frontend* fe) |
241 | { | 247 | { |
242 | struct dvb_bt8xx_card *card = fe->dvb->priv; | 248 | struct dvb_bt8xx_card *card = fe->dvb->priv; |
243 | 249 | ||
@@ -247,7 +253,7 @@ static int pinnsat_pll_init(struct dvb_frontend* fe) | |||
247 | return 0; | 253 | return 0; |
248 | } | 254 | } |
249 | 255 | ||
250 | static int pinnsat_pll_sleep(struct dvb_frontend* fe) | 256 | static int pinnsat_tuner_sleep(struct dvb_frontend* fe) |
251 | { | 257 | { |
252 | struct dvb_bt8xx_card *card = fe->dvb->priv; | 258 | struct dvb_bt8xx_card *card = fe->dvb->priv; |
253 | 259 | ||
@@ -258,12 +264,9 @@ static int pinnsat_pll_sleep(struct dvb_frontend* fe) | |||
258 | 264 | ||
259 | static struct cx24110_config pctvsat_config = { | 265 | static struct cx24110_config pctvsat_config = { |
260 | .demod_address = 0x55, | 266 | .demod_address = 0x55, |
261 | .pll_init = pinnsat_pll_init, | ||
262 | .pll_set = cx24108_pll_set, | ||
263 | .pll_sleep = pinnsat_pll_sleep, | ||
264 | }; | 267 | }; |
265 | 268 | ||
266 | static int microtune_mt7202dtf_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 269 | static int microtune_mt7202dtf_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) |
267 | { | 270 | { |
268 | struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv; | 271 | struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv; |
269 | u8 cfg, cpump, band_select; | 272 | u8 cfg, cpump, band_select; |
@@ -297,6 +300,8 @@ static int microtune_mt7202dtf_pll_set(struct dvb_frontend* fe, struct dvb_front | |||
297 | data[2] = ((div >> 10) & 0x60) | cfg; | 300 | data[2] = ((div >> 10) & 0x60) | cfg; |
298 | data[3] = (cpump << 6) | band_select; | 301 | data[3] = (cpump << 6) | band_select; |
299 | 302 | ||
303 | if (fe->ops.i2c_gate_ctrl) | ||
304 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
300 | i2c_transfer(card->i2c_adapter, &msg, 1); | 305 | i2c_transfer(card->i2c_adapter, &msg, 1); |
301 | return (div * 166666 - 36000000); | 306 | return (div * 166666 - 36000000); |
302 | } | 307 | } |
@@ -310,7 +315,6 @@ static int microtune_mt7202dtf_request_firmware(struct dvb_frontend* fe, const s | |||
310 | 315 | ||
311 | static struct sp887x_config microtune_mt7202dtf_config = { | 316 | static struct sp887x_config microtune_mt7202dtf_config = { |
312 | .demod_address = 0x70, | 317 | .demod_address = 0x70, |
313 | .pll_set = microtune_mt7202dtf_pll_set, | ||
314 | .request_firmware = microtune_mt7202dtf_request_firmware, | 318 | .request_firmware = microtune_mt7202dtf_request_firmware, |
315 | }; | 319 | }; |
316 | 320 | ||
@@ -337,12 +341,14 @@ static int advbt771_samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe) | |||
337 | return 0; | 341 | return 0; |
338 | } | 342 | } |
339 | 343 | ||
340 | static int advbt771_samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf) | 344 | static int advbt771_samsung_tdtc9251dh0_tuner_calc_regs(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf, int buf_len) |
341 | { | 345 | { |
342 | u32 div; | 346 | u32 div; |
343 | unsigned char bs = 0; | 347 | unsigned char bs = 0; |
344 | unsigned char cp = 0; | 348 | unsigned char cp = 0; |
345 | 349 | ||
350 | if (buf_len < 5) return -EINVAL; | ||
351 | |||
346 | div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; | 352 | div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; |
347 | 353 | ||
348 | if (params->frequency < 150000000) | 354 | if (params->frequency < 150000000) |
@@ -383,19 +389,18 @@ static int advbt771_samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct | |||
383 | else | 389 | else |
384 | bs = 0x08; | 390 | bs = 0x08; |
385 | 391 | ||
386 | pllbuf[0] = 0xc2; // Note: non-linux standard PLL i2c address | 392 | pllbuf[0] = 0x61; |
387 | pllbuf[1] = div >> 8; | 393 | pllbuf[1] = div >> 8; |
388 | pllbuf[2] = div & 0xff; | 394 | pllbuf[2] = div & 0xff; |
389 | pllbuf[3] = cp; | 395 | pllbuf[3] = cp; |
390 | pllbuf[4] = bs; | 396 | pllbuf[4] = bs; |
391 | 397 | ||
392 | return 0; | 398 | return 5; |
393 | } | 399 | } |
394 | 400 | ||
395 | static struct mt352_config advbt771_samsung_tdtc9251dh0_config = { | 401 | static struct mt352_config advbt771_samsung_tdtc9251dh0_config = { |
396 | .demod_address = 0x0f, | 402 | .demod_address = 0x0f, |
397 | .demod_init = advbt771_samsung_tdtc9251dh0_demod_init, | 403 | .demod_init = advbt771_samsung_tdtc9251dh0_demod_init, |
398 | .pll_set = advbt771_samsung_tdtc9251dh0_pll_set, | ||
399 | }; | 404 | }; |
400 | 405 | ||
401 | static struct dst_config dst_config = { | 406 | static struct dst_config dst_config = { |
@@ -455,7 +460,7 @@ static struct or51211_config or51211_config = { | |||
455 | .sleep = or51211_sleep, | 460 | .sleep = or51211_sleep, |
456 | }; | 461 | }; |
457 | 462 | ||
458 | static int vp3021_alps_tded4_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 463 | static int vp3021_alps_tded4_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) |
459 | { | 464 | { |
460 | struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv; | 465 | struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv; |
461 | u8 buf[4]; | 466 | u8 buf[4]; |
@@ -478,6 +483,8 @@ static int vp3021_alps_tded4_pll_set(struct dvb_frontend* fe, struct dvb_fronten | |||
478 | else | 483 | else |
479 | return -EINVAL; | 484 | return -EINVAL; |
480 | 485 | ||
486 | if (fe->ops.i2c_gate_ctrl) | ||
487 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
481 | i2c_transfer(card->i2c_adapter, &msg, 1); | 488 | i2c_transfer(card->i2c_adapter, &msg, 1); |
482 | return 0; | 489 | return 0; |
483 | } | 490 | } |
@@ -485,7 +492,6 @@ static int vp3021_alps_tded4_pll_set(struct dvb_frontend* fe, struct dvb_fronten | |||
485 | static struct nxt6000_config vp3021_alps_tded4_config = { | 492 | static struct nxt6000_config vp3021_alps_tded4_config = { |
486 | .demod_address = 0x0a, | 493 | .demod_address = 0x0a, |
487 | .clock_inversion = 1, | 494 | .clock_inversion = 1, |
488 | .pll_set = vp3021_alps_tded4_pll_set, | ||
489 | }; | 495 | }; |
490 | 496 | ||
491 | static int digitv_alps_tded4_demod_init(struct dvb_frontend* fe) | 497 | static int digitv_alps_tded4_demod_init(struct dvb_frontend* fe) |
@@ -506,14 +512,17 @@ static int digitv_alps_tded4_demod_init(struct dvb_frontend* fe) | |||
506 | return 0; | 512 | return 0; |
507 | } | 513 | } |
508 | 514 | ||
509 | static int digitv_alps_tded4_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf) | 515 | static int digitv_alps_tded4_tuner_calc_regs(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf, int buf_len) |
510 | { | 516 | { |
511 | u32 div; | 517 | u32 div; |
512 | struct dvb_ofdm_parameters *op = ¶ms->u.ofdm; | 518 | struct dvb_ofdm_parameters *op = ¶ms->u.ofdm; |
513 | 519 | ||
520 | if (buf_len < 5) | ||
521 | return -EINVAL; | ||
522 | |||
514 | div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; | 523 | div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; |
515 | 524 | ||
516 | pllbuf[0] = 0xc2; | 525 | pllbuf[0] = 0x61; |
517 | pllbuf[1] = (div >> 8) & 0x7F; | 526 | pllbuf[1] = (div >> 8) & 0x7F; |
518 | pllbuf[2] = div & 0xFF; | 527 | pllbuf[2] = div & 0xFF; |
519 | pllbuf[3] = 0x85; | 528 | pllbuf[3] = 0x85; |
@@ -530,7 +539,7 @@ static int digitv_alps_tded4_pll_set(struct dvb_frontend* fe, struct dvb_fronten | |||
530 | if (op->bandwidth == 8) | 539 | if (op->bandwidth == 8) |
531 | pllbuf[4] |= 0x04; | 540 | pllbuf[4] |= 0x04; |
532 | 541 | ||
533 | return 0; | 542 | return 5; |
534 | } | 543 | } |
535 | 544 | ||
536 | static void digitv_alps_tded4_reset(struct dvb_bt8xx_card *bt) | 545 | static void digitv_alps_tded4_reset(struct dvb_bt8xx_card *bt) |
@@ -557,43 +566,18 @@ static void digitv_alps_tded4_reset(struct dvb_bt8xx_card *bt) | |||
557 | static struct mt352_config digitv_alps_tded4_config = { | 566 | static struct mt352_config digitv_alps_tded4_config = { |
558 | .demod_address = 0x0a, | 567 | .demod_address = 0x0a, |
559 | .demod_init = digitv_alps_tded4_demod_init, | 568 | .demod_init = digitv_alps_tded4_demod_init, |
560 | .pll_set = digitv_alps_tded4_pll_set, | ||
561 | }; | 569 | }; |
562 | 570 | ||
563 | static int tdvs_tua6034_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 571 | static int tdvs_tua6034_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) |
564 | { | 572 | { |
565 | struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv; | 573 | struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv; |
566 | u8 buf[4]; | 574 | return lg_h06xf_pll_set(fe, card->i2c_adapter, params); |
567 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; | ||
568 | int err; | ||
569 | |||
570 | dvb_pll_configure(&dvb_pll_tdvs_tua6034, buf, params->frequency, 0); | ||
571 | dprintk("%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n", | ||
572 | __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]); | ||
573 | if ((err = i2c_transfer(card->i2c_adapter, &msg, 1)) != 1) { | ||
574 | printk(KERN_WARNING "dvb-bt8xx: %s error " | ||
575 | "(addr %02x <- %02x, err = %i)\n", | ||
576 | __FUNCTION__, buf[0], buf[1], err); | ||
577 | if (err < 0) | ||
578 | return err; | ||
579 | else | ||
580 | return -EREMOTEIO; | ||
581 | } | ||
582 | |||
583 | /* Set the Auxiliary Byte. */ | ||
584 | buf[2] &= ~0x20; | ||
585 | buf[2] |= 0x18; | ||
586 | buf[3] = 0x50; | ||
587 | i2c_transfer(card->i2c_adapter, &msg, 1); | ||
588 | |||
589 | return 0; | ||
590 | } | 575 | } |
591 | 576 | ||
592 | static struct lgdt330x_config tdvs_tua6034_config = { | 577 | static struct lgdt330x_config tdvs_tua6034_config = { |
593 | .demod_address = 0x0e, | 578 | .demod_address = 0x0e, |
594 | .demod_chip = LGDT3303, | 579 | .demod_chip = LGDT3303, |
595 | .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */ | 580 | .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */ |
596 | .pll_set = tdvs_tua6034_pll_set, | ||
597 | }; | 581 | }; |
598 | 582 | ||
599 | static void lgdt330x_reset(struct dvb_bt8xx_card *bt) | 583 | static void lgdt330x_reset(struct dvb_bt8xx_card *bt) |
@@ -617,17 +601,25 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) | |||
617 | switch(type) { | 601 | switch(type) { |
618 | case BTTV_BOARD_DVICO_DVBT_LITE: | 602 | case BTTV_BOARD_DVICO_DVBT_LITE: |
619 | card->fe = mt352_attach(&thomson_dtt7579_config, card->i2c_adapter); | 603 | card->fe = mt352_attach(&thomson_dtt7579_config, card->i2c_adapter); |
604 | |||
605 | if (card->fe == NULL) | ||
606 | card->fe = zl10353_attach(&thomson_dtt7579_zl10353_config, | ||
607 | card->i2c_adapter); | ||
608 | |||
620 | if (card->fe != NULL) { | 609 | if (card->fe != NULL) { |
621 | card->fe->ops->info.frequency_min = 174000000; | 610 | card->fe->ops.tuner_ops.calc_regs = thomson_dtt7579_tuner_calc_regs; |
622 | card->fe->ops->info.frequency_max = 862000000; | 611 | card->fe->ops.info.frequency_min = 174000000; |
612 | card->fe->ops.info.frequency_max = 862000000; | ||
623 | } | 613 | } |
624 | break; | 614 | break; |
625 | 615 | ||
626 | case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE: | 616 | case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE: |
627 | lgdt330x_reset(card); | 617 | lgdt330x_reset(card); |
628 | card->fe = lgdt330x_attach(&tdvs_tua6034_config, card->i2c_adapter); | 618 | card->fe = lgdt330x_attach(&tdvs_tua6034_config, card->i2c_adapter); |
629 | if (card->fe != NULL) | 619 | if (card->fe != NULL) { |
620 | card->fe->ops.tuner_ops.set_params = tdvs_tua6034_tuner_set_params; | ||
630 | dprintk ("dvb_bt8xx: lgdt330x detected\n"); | 621 | dprintk ("dvb_bt8xx: lgdt330x detected\n"); |
622 | } | ||
631 | break; | 623 | break; |
632 | 624 | ||
633 | case BTTV_BOARD_NEBULA_DIGITV: | 625 | case BTTV_BOARD_NEBULA_DIGITV: |
@@ -640,6 +632,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) | |||
640 | digitv_alps_tded4_reset(card); | 632 | digitv_alps_tded4_reset(card); |
641 | card->fe = nxt6000_attach(&vp3021_alps_tded4_config, card->i2c_adapter); | 633 | card->fe = nxt6000_attach(&vp3021_alps_tded4_config, card->i2c_adapter); |
642 | if (card->fe != NULL) { | 634 | if (card->fe != NULL) { |
635 | card->fe->ops.tuner_ops.set_params = vp3021_alps_tded4_tuner_set_params; | ||
643 | dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n"); | 636 | dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n"); |
644 | break; | 637 | break; |
645 | } | 638 | } |
@@ -648,19 +641,25 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) | |||
648 | digitv_alps_tded4_reset(card); | 641 | digitv_alps_tded4_reset(card); |
649 | card->fe = mt352_attach(&digitv_alps_tded4_config, card->i2c_adapter); | 642 | card->fe = mt352_attach(&digitv_alps_tded4_config, card->i2c_adapter); |
650 | 643 | ||
651 | if (card->fe != NULL) | 644 | if (card->fe != NULL) { |
645 | card->fe->ops.tuner_ops.calc_regs = digitv_alps_tded4_tuner_calc_regs; | ||
652 | dprintk ("dvb_bt8xx: an mt352 was detected on your digitv card\n"); | 646 | dprintk ("dvb_bt8xx: an mt352 was detected on your digitv card\n"); |
647 | } | ||
653 | break; | 648 | break; |
654 | 649 | ||
655 | case BTTV_BOARD_AVDVBT_761: | 650 | case BTTV_BOARD_AVDVBT_761: |
656 | card->fe = sp887x_attach(µtune_mt7202dtf_config, card->i2c_adapter); | 651 | card->fe = sp887x_attach(µtune_mt7202dtf_config, card->i2c_adapter); |
652 | if (card->fe) { | ||
653 | card->fe->ops.tuner_ops.set_params = microtune_mt7202dtf_tuner_set_params; | ||
654 | } | ||
657 | break; | 655 | break; |
658 | 656 | ||
659 | case BTTV_BOARD_AVDVBT_771: | 657 | case BTTV_BOARD_AVDVBT_771: |
660 | card->fe = mt352_attach(&advbt771_samsung_tdtc9251dh0_config, card->i2c_adapter); | 658 | card->fe = mt352_attach(&advbt771_samsung_tdtc9251dh0_config, card->i2c_adapter); |
661 | if (card->fe != NULL) { | 659 | if (card->fe != NULL) { |
662 | card->fe->ops->info.frequency_min = 174000000; | 660 | card->fe->ops.tuner_ops.calc_regs = advbt771_samsung_tdtc9251dh0_tuner_calc_regs; |
663 | card->fe->ops->info.frequency_max = 862000000; | 661 | card->fe->ops.info.frequency_min = 174000000; |
662 | card->fe->ops.info.frequency_max = 862000000; | ||
664 | } | 663 | } |
665 | break; | 664 | break; |
666 | 665 | ||
@@ -687,6 +686,11 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) | |||
687 | 686 | ||
688 | case BTTV_BOARD_PINNACLESAT: | 687 | case BTTV_BOARD_PINNACLESAT: |
689 | card->fe = cx24110_attach(&pctvsat_config, card->i2c_adapter); | 688 | card->fe = cx24110_attach(&pctvsat_config, card->i2c_adapter); |
689 | if (card->fe) { | ||
690 | card->fe->ops.tuner_ops.init = pinnsat_tuner_init; | ||
691 | card->fe->ops.tuner_ops.sleep = pinnsat_tuner_sleep; | ||
692 | card->fe->ops.tuner_ops.set_params = cx24108_tuner_set_params; | ||
693 | } | ||
690 | break; | 694 | break; |
691 | 695 | ||
692 | case BTTV_BOARD_PC_HDTV: | 696 | case BTTV_BOARD_PC_HDTV: |
@@ -703,8 +707,8 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) | |||
703 | else | 707 | else |
704 | if (dvb_register_frontend(&card->dvb_adapter, card->fe)) { | 708 | if (dvb_register_frontend(&card->dvb_adapter, card->fe)) { |
705 | printk("dvb-bt8xx: Frontend registration failed!\n"); | 709 | printk("dvb-bt8xx: Frontend registration failed!\n"); |
706 | if (card->fe->ops->release) | 710 | if (card->fe->ops.release) |
707 | card->fe->ops->release(card->fe); | 711 | card->fe->ops.release(card->fe); |
708 | card->fe = NULL; | 712 | card->fe = NULL; |
709 | } | 713 | } |
710 | } | 714 | } |
@@ -713,7 +717,7 @@ static int __devinit dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type) | |||
713 | { | 717 | { |
714 | int result; | 718 | int result; |
715 | 719 | ||
716 | if ((result = dvb_register_adapter(&card->dvb_adapter, card->card_name, THIS_MODULE)) < 0) { | 720 | if ((result = dvb_register_adapter(&card->dvb_adapter, card->card_name, THIS_MODULE, &card->bt->dev->dev)) < 0) { |
717 | printk("dvb_bt8xx: dvb_register_adapter failed (errno = %d)\n", result); | 721 | printk("dvb_bt8xx: dvb_register_adapter failed (errno = %d)\n", result); |
718 | return result; | 722 | return result; |
719 | } | 723 | } |
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.h b/drivers/media/dvb/bt8xx/dvb-bt8xx.h index 00dd9fa54c82..4745a9017a19 100644 --- a/drivers/media/dvb/bt8xx/dvb-bt8xx.h +++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.h | |||
@@ -37,6 +37,8 @@ | |||
37 | #include "cx24110.h" | 37 | #include "cx24110.h" |
38 | #include "or51211.h" | 38 | #include "or51211.h" |
39 | #include "lgdt330x.h" | 39 | #include "lgdt330x.h" |
40 | #include "lg_h06xf.h" | ||
41 | #include "zl10353.h" | ||
40 | 42 | ||
41 | struct dvb_bt8xx_card { | 43 | struct dvb_bt8xx_card { |
42 | struct mutex lock; | 44 | struct mutex lock; |
diff --git a/drivers/media/dvb/cinergyT2/Kconfig b/drivers/media/dvb/cinergyT2/Kconfig index 6018fcdba1e6..b5cdd57ec6f5 100644 --- a/drivers/media/dvb/cinergyT2/Kconfig +++ b/drivers/media/dvb/cinergyT2/Kconfig | |||
@@ -64,7 +64,7 @@ config DVB_CINERGYT2_QUERY_INTERVAL | |||
64 | config DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE | 64 | config DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE |
65 | bool "Register the onboard IR Remote Control Receiver as Input Device" | 65 | bool "Register the onboard IR Remote Control Receiver as Input Device" |
66 | depends on DVB_CINERGYT2_TUNING | 66 | depends on DVB_CINERGYT2_TUNING |
67 | default "yes" | 67 | default y |
68 | help | 68 | help |
69 | Enable this option if you want to use the onboard Infrared Remote | 69 | Enable this option if you want to use the onboard Infrared Remote |
70 | Control Receiver as Linux-Input device. | 70 | Control Receiver as Linux-Input device. |
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c index 9325d039ea65..1b8953600425 100644 --- a/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/drivers/media/dvb/cinergyT2/cinergyT2.c | |||
@@ -544,15 +544,19 @@ static unsigned int cinergyt2_poll (struct file *file, struct poll_table_struct | |||
544 | { | 544 | { |
545 | struct dvb_device *dvbdev = file->private_data; | 545 | struct dvb_device *dvbdev = file->private_data; |
546 | struct cinergyt2 *cinergyt2 = dvbdev->priv; | 546 | struct cinergyt2 *cinergyt2 = dvbdev->priv; |
547 | unsigned int mask = 0; | ||
547 | 548 | ||
548 | if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) | 549 | if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) |
549 | return -ERESTARTSYS; | 550 | return -ERESTARTSYS; |
550 | 551 | ||
551 | poll_wait(file, &cinergyt2->poll_wq, wait); | 552 | poll_wait(file, &cinergyt2->poll_wq, wait); |
552 | 553 | ||
554 | if (cinergyt2->pending_fe_events != 0) | ||
555 | mask |= (POLLIN | POLLRDNORM | POLLPRI); | ||
556 | |||
553 | mutex_unlock(&cinergyt2->sem); | 557 | mutex_unlock(&cinergyt2->sem); |
554 | 558 | ||
555 | return (POLLIN | POLLRDNORM | POLLPRI); | 559 | return mask; |
556 | } | 560 | } |
557 | 561 | ||
558 | 562 | ||
@@ -902,7 +906,7 @@ static int cinergyt2_probe (struct usb_interface *intf, | |||
902 | return -ENOMEM; | 906 | return -ENOMEM; |
903 | } | 907 | } |
904 | 908 | ||
905 | if ((err = dvb_register_adapter(&cinergyt2->adapter, DRIVER_NAME, THIS_MODULE)) < 0) { | 909 | if ((err = dvb_register_adapter(&cinergyt2->adapter, DRIVER_NAME, THIS_MODULE, &cinergyt2->udev->dev)) < 0) { |
906 | kfree(cinergyt2); | 910 | kfree(cinergyt2); |
907 | return err; | 911 | return err; |
908 | } | 912 | } |
diff --git a/drivers/media/dvb/dvb-core/Makefile b/drivers/media/dvb/dvb-core/Makefile index 7adb50c1e8eb..11054657fdb5 100644 --- a/drivers/media/dvb/dvb-core/Makefile +++ b/drivers/media/dvb/dvb-core/Makefile | |||
@@ -2,8 +2,8 @@ | |||
2 | # Makefile for the kernel DVB device drivers. | 2 | # Makefile for the kernel DVB device drivers. |
3 | # | 3 | # |
4 | 4 | ||
5 | dvb-core-objs = dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \ | 5 | dvb-core-objs = dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \ |
6 | dvb_ca_en50221.o dvb_frontend.o \ | 6 | dvb_ca_en50221.o dvb_frontend.o \ |
7 | dvb_net.o dvb_ringbuffer.o | 7 | dvb_net.o dvb_ringbuffer.o dvb_math.o |
8 | 8 | ||
9 | obj-$(CONFIG_DVB_CORE) += dvb-core.o | 9 | obj-$(CONFIG_DVB_CORE) += dvb-core.o |
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c index 04578df3f249..988499dfddf8 100644 --- a/drivers/media/dvb/dvb-core/dmxdev.c +++ b/drivers/media/dvb/dvb-core/dmxdev.c | |||
@@ -872,9 +872,6 @@ static int dvb_demux_do_ioctl(struct inode *inode, struct file *file, | |||
872 | mutex_unlock(&dmxdevfilter->mutex); | 872 | mutex_unlock(&dmxdevfilter->mutex); |
873 | break; | 873 | break; |
874 | 874 | ||
875 | case DMX_GET_EVENT: | ||
876 | break; | ||
877 | |||
878 | case DMX_GET_PES_PIDS: | 875 | case DMX_GET_PES_PIDS: |
879 | if (!dmxdev->demux->get_pes_pids) { | 876 | if (!dmxdev->demux->get_pes_pids) { |
880 | ret = -EINVAL; | 877 | ret = -EINVAL; |
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c index 00347a750681..2a03bf53cb29 100644 --- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c | |||
@@ -1060,8 +1060,18 @@ static int dvb_ca_en50221_thread(void *data) | |||
1060 | break; | 1060 | break; |
1061 | 1061 | ||
1062 | case DVB_CA_SLOTSTATE_VALIDATE: | 1062 | case DVB_CA_SLOTSTATE_VALIDATE: |
1063 | if (dvb_ca_en50221_parse_attributes(ca, slot) | 1063 | if (dvb_ca_en50221_parse_attributes(ca, slot) != 0) { |
1064 | != 0) { | 1064 | /* we need this extra check for annoying interfaces like the budget-av */ |
1065 | if ((!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) && | ||
1066 | (ca->pub->poll_slot_status)) { | ||
1067 | int status = ca->pub->poll_slot_status(ca->pub, slot, 0); | ||
1068 | if (!(status & DVB_CA_EN50221_POLL_CAM_PRESENT)) { | ||
1069 | ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE; | ||
1070 | dvb_ca_en50221_thread_update_delay(ca); | ||
1071 | break; | ||
1072 | } | ||
1073 | } | ||
1074 | |||
1065 | printk("dvb_ca adapter %d: Invalid PC card inserted :(\n", | 1075 | printk("dvb_ca adapter %d: Invalid PC card inserted :(\n", |
1066 | ca->dvbdev->adapter->num); | 1076 | ca->dvbdev->adapter->num); |
1067 | ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID; | 1077 | ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID; |
@@ -1108,6 +1118,17 @@ static int dvb_ca_en50221_thread(void *data) | |||
1108 | 1118 | ||
1109 | case DVB_CA_SLOTSTATE_LINKINIT: | 1119 | case DVB_CA_SLOTSTATE_LINKINIT: |
1110 | if (dvb_ca_en50221_link_init(ca, slot) != 0) { | 1120 | if (dvb_ca_en50221_link_init(ca, slot) != 0) { |
1121 | /* we need this extra check for annoying interfaces like the budget-av */ | ||
1122 | if ((!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) && | ||
1123 | (ca->pub->poll_slot_status)) { | ||
1124 | int status = ca->pub->poll_slot_status(ca->pub, slot, 0); | ||
1125 | if (!(status & DVB_CA_EN50221_POLL_CAM_PRESENT)) { | ||
1126 | ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE; | ||
1127 | dvb_ca_en50221_thread_update_delay(ca); | ||
1128 | break; | ||
1129 | } | ||
1130 | } | ||
1131 | |||
1111 | printk("dvb_ca adapter %d: DVB CAM link initialisation failed :(\n", ca->dvbdev->adapter->num); | 1132 | printk("dvb_ca adapter %d: DVB CAM link initialisation failed :(\n", ca->dvbdev->adapter->num); |
1112 | ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID; | 1133 | ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID; |
1113 | dvb_ca_en50221_thread_update_delay(ca); | 1134 | dvb_ca_en50221_thread_update_delay(ca); |
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c index 83ec5e06c482..fcff5eab21a3 100644 --- a/drivers/media/dvb/dvb-core/dvb_demux.c +++ b/drivers/media/dvb/dvb-core/dvb_demux.c | |||
@@ -473,7 +473,7 @@ void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count) | |||
473 | goto bailout; | 473 | goto bailout; |
474 | } | 474 | } |
475 | memcpy(&demux->tsbuf[i], buf, j); | 475 | memcpy(&demux->tsbuf[i], buf, j); |
476 | if ((demux->tsbuf[0] == 0x47) | (demux->tsbuf[0] == 0xB8)) { | 476 | if ((demux->tsbuf[0] == 0x47) || (demux->tsbuf[0] == 0xB8)) { |
477 | memcpy(tmppack, demux->tsbuf, 188); | 477 | memcpy(tmppack, demux->tsbuf, 188); |
478 | if (tmppack[0] == 0xB8) | 478 | if (tmppack[0] == 0xB8) |
479 | tmppack[0] = 0x47; | 479 | tmppack[0] = 0x47; |
@@ -484,7 +484,7 @@ void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count) | |||
484 | } | 484 | } |
485 | 485 | ||
486 | while (p < count) { | 486 | while (p < count) { |
487 | if ((buf[p] == 0x47) | (buf[p] == 0xB8)) { | 487 | if ((buf[p] == 0x47) || (buf[p] == 0xB8)) { |
488 | if (count - p >= 204) { | 488 | if (count - p >= 204) { |
489 | memcpy(tmppack, &buf[p], 188); | 489 | memcpy(tmppack, &buf[p], 188); |
490 | if (tmppack[0] == 0xB8) | 490 | if (tmppack[0] == 0xB8) |
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index a051790161b0..3152a54a2539 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c | |||
@@ -56,7 +56,7 @@ MODULE_PARM_DESC(dvb_force_auto_inversion, "0: normal (default), 1: INVERSION_AU | |||
56 | module_param(dvb_override_tune_delay, int, 0644); | 56 | module_param(dvb_override_tune_delay, int, 0644); |
57 | MODULE_PARM_DESC(dvb_override_tune_delay, "0: normal (default), >0 => delay in milliseconds to wait for lock after a tune attempt"); | 57 | MODULE_PARM_DESC(dvb_override_tune_delay, "0: normal (default), >0 => delay in milliseconds to wait for lock after a tune attempt"); |
58 | module_param(dvb_powerdown_on_sleep, int, 0644); | 58 | module_param(dvb_powerdown_on_sleep, int, 0644); |
59 | MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB volatage off on sleep (default)"); | 59 | MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB voltage off on sleep (default)"); |
60 | 60 | ||
61 | #define dprintk if (dvb_frontend_debug) printk | 61 | #define dprintk if (dvb_frontend_debug) printk |
62 | 62 | ||
@@ -72,6 +72,8 @@ MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB vola | |||
72 | #define FESTATE_SEARCHING_FAST (FESTATE_TUNING_FAST | FESTATE_ZIGZAG_FAST) | 72 | #define FESTATE_SEARCHING_FAST (FESTATE_TUNING_FAST | FESTATE_ZIGZAG_FAST) |
73 | #define FESTATE_SEARCHING_SLOW (FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_SLOW) | 73 | #define FESTATE_SEARCHING_SLOW (FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_SLOW) |
74 | #define FESTATE_LOSTLOCK (FESTATE_ZIGZAG_FAST | FESTATE_ZIGZAG_SLOW) | 74 | #define FESTATE_LOSTLOCK (FESTATE_ZIGZAG_FAST | FESTATE_ZIGZAG_SLOW) |
75 | |||
76 | #define FE_ALGO_HW 1 | ||
75 | /* | 77 | /* |
76 | * FESTATE_IDLE. No tuning parameters have been supplied and the loop is idling. | 78 | * FESTATE_IDLE. No tuning parameters have been supplied and the loop is idling. |
77 | * FESTATE_RETUNE. Parameters have been supplied, but we have not yet performed the first tune. | 79 | * FESTATE_RETUNE. Parameters have been supplied, but we have not yet performed the first tune. |
@@ -151,8 +153,8 @@ static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status) | |||
151 | sizeof (struct dvb_frontend_parameters)); | 153 | sizeof (struct dvb_frontend_parameters)); |
152 | 154 | ||
153 | if (status & FE_HAS_LOCK) | 155 | if (status & FE_HAS_LOCK) |
154 | if (fe->ops->get_frontend) | 156 | if (fe->ops.get_frontend) |
155 | fe->ops->get_frontend(fe, &e->parameters); | 157 | fe->ops.get_frontend(fe, &e->parameters); |
156 | 158 | ||
157 | events->eventw = wp; | 159 | events->eventw = wp; |
158 | 160 | ||
@@ -211,10 +213,15 @@ static void dvb_frontend_init(struct dvb_frontend *fe) | |||
211 | { | 213 | { |
212 | dprintk ("DVB: initialising frontend %i (%s)...\n", | 214 | dprintk ("DVB: initialising frontend %i (%s)...\n", |
213 | fe->dvb->num, | 215 | fe->dvb->num, |
214 | fe->ops->info.name); | 216 | fe->ops.info.name); |
215 | 217 | ||
216 | if (fe->ops->init) | 218 | if (fe->ops.init) |
217 | fe->ops->init(fe); | 219 | fe->ops.init(fe); |
220 | if (fe->ops.tuner_ops.init) { | ||
221 | fe->ops.tuner_ops.init(fe); | ||
222 | if (fe->ops.i2c_gate_ctrl) | ||
223 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
224 | } | ||
218 | } | 225 | } |
219 | 226 | ||
220 | void dvb_frontend_reinitialise(struct dvb_frontend *fe) | 227 | void dvb_frontend_reinitialise(struct dvb_frontend *fe) |
@@ -259,7 +266,7 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra | |||
259 | u32 original_frequency = fepriv->parameters.frequency; | 266 | u32 original_frequency = fepriv->parameters.frequency; |
260 | 267 | ||
261 | /* are we using autoinversion? */ | 268 | /* are we using autoinversion? */ |
262 | autoinversion = ((!(fe->ops->info.caps & FE_CAN_INVERSION_AUTO)) && | 269 | autoinversion = ((!(fe->ops.info.caps & FE_CAN_INVERSION_AUTO)) && |
263 | (fepriv->parameters.inversion == INVERSION_AUTO)); | 270 | (fepriv->parameters.inversion == INVERSION_AUTO)); |
264 | 271 | ||
265 | /* setup parameters correctly */ | 272 | /* setup parameters correctly */ |
@@ -329,8 +336,8 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra | |||
329 | fepriv->parameters.frequency += fepriv->lnb_drift; | 336 | fepriv->parameters.frequency += fepriv->lnb_drift; |
330 | if (autoinversion) | 337 | if (autoinversion) |
331 | fepriv->parameters.inversion = fepriv->inversion; | 338 | fepriv->parameters.inversion = fepriv->inversion; |
332 | if (fe->ops->set_frontend) | 339 | if (fe->ops.set_frontend) |
333 | fe->ops->set_frontend(fe, &fepriv->parameters); | 340 | fe->ops.set_frontend(fe, &fepriv->parameters); |
334 | 341 | ||
335 | fepriv->parameters.frequency = original_frequency; | 342 | fepriv->parameters.frequency = original_frequency; |
336 | fepriv->parameters.inversion = original_inversion; | 343 | fepriv->parameters.inversion = original_inversion; |
@@ -354,8 +361,8 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe) | |||
354 | /* in SCAN mode, we just set the frontend when asked and leave it alone */ | 361 | /* in SCAN mode, we just set the frontend when asked and leave it alone */ |
355 | if (fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT) { | 362 | if (fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT) { |
356 | if (fepriv->state & FESTATE_RETUNE) { | 363 | if (fepriv->state & FESTATE_RETUNE) { |
357 | if (fe->ops->set_frontend) | 364 | if (fe->ops.set_frontend) |
358 | fe->ops->set_frontend(fe, &fepriv->parameters); | 365 | fe->ops.set_frontend(fe, &fepriv->parameters); |
359 | fepriv->state = FESTATE_TUNED; | 366 | fepriv->state = FESTATE_TUNED; |
360 | } | 367 | } |
361 | fepriv->delay = 3*HZ; | 368 | fepriv->delay = 3*HZ; |
@@ -367,8 +374,8 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe) | |||
367 | if (fepriv->state & FESTATE_RETUNE) { | 374 | if (fepriv->state & FESTATE_RETUNE) { |
368 | s = 0; | 375 | s = 0; |
369 | } else { | 376 | } else { |
370 | if (fe->ops->read_status) | 377 | if (fe->ops.read_status) |
371 | fe->ops->read_status(fe, &s); | 378 | fe->ops.read_status(fe, &s); |
372 | if (s != fepriv->status) { | 379 | if (s != fepriv->status) { |
373 | dvb_frontend_add_event(fe, s); | 380 | dvb_frontend_add_event(fe, s); |
374 | fepriv->status = s; | 381 | fepriv->status = s; |
@@ -381,7 +388,7 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe) | |||
381 | fepriv->state = FESTATE_TUNED; | 388 | fepriv->state = FESTATE_TUNED; |
382 | 389 | ||
383 | /* if we're tuned, then we have determined the correct inversion */ | 390 | /* if we're tuned, then we have determined the correct inversion */ |
384 | if ((!(fe->ops->info.caps & FE_CAN_INVERSION_AUTO)) && | 391 | if ((!(fe->ops.info.caps & FE_CAN_INVERSION_AUTO)) && |
385 | (fepriv->parameters.inversion == INVERSION_AUTO)) { | 392 | (fepriv->parameters.inversion == INVERSION_AUTO)) { |
386 | fepriv->parameters.inversion = fepriv->inversion; | 393 | fepriv->parameters.inversion = fepriv->inversion; |
387 | } | 394 | } |
@@ -405,7 +412,7 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe) | |||
405 | /* don't actually do anything if we're in the LOSTLOCK state, | 412 | /* don't actually do anything if we're in the LOSTLOCK state, |
406 | * the frontend is set to FE_CAN_RECOVER, and the max_drift is 0 */ | 413 | * the frontend is set to FE_CAN_RECOVER, and the max_drift is 0 */ |
407 | if ((fepriv->state & FESTATE_LOSTLOCK) && | 414 | if ((fepriv->state & FESTATE_LOSTLOCK) && |
408 | (fe->ops->info.caps & FE_CAN_RECOVER) && (fepriv->max_drift == 0)) { | 415 | (fe->ops.info.caps & FE_CAN_RECOVER) && (fepriv->max_drift == 0)) { |
409 | dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK); | 416 | dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK); |
410 | return; | 417 | return; |
411 | } | 418 | } |
@@ -540,16 +547,16 @@ static int dvb_frontend_thread(void *data) | |||
540 | if (fepriv->reinitialise) { | 547 | if (fepriv->reinitialise) { |
541 | dvb_frontend_init(fe); | 548 | dvb_frontend_init(fe); |
542 | if (fepriv->tone != -1) { | 549 | if (fepriv->tone != -1) { |
543 | fe->ops->set_tone(fe, fepriv->tone); | 550 | fe->ops.set_tone(fe, fepriv->tone); |
544 | } | 551 | } |
545 | if (fepriv->voltage != -1) { | 552 | if (fepriv->voltage != -1) { |
546 | fe->ops->set_voltage(fe, fepriv->voltage); | 553 | fe->ops.set_voltage(fe, fepriv->voltage); |
547 | } | 554 | } |
548 | fepriv->reinitialise = 0; | 555 | fepriv->reinitialise = 0; |
549 | } | 556 | } |
550 | 557 | ||
551 | /* do an iteration of the tuning loop */ | 558 | /* do an iteration of the tuning loop */ |
552 | if (fe->ops->tune) { | 559 | if (fe->ops.get_frontend_algo(fe) == FE_ALGO_HW) { |
553 | /* have we been asked to retune? */ | 560 | /* have we been asked to retune? */ |
554 | params = NULL; | 561 | params = NULL; |
555 | if (fepriv->state & FESTATE_RETUNE) { | 562 | if (fepriv->state & FESTATE_RETUNE) { |
@@ -557,7 +564,7 @@ static int dvb_frontend_thread(void *data) | |||
557 | fepriv->state = FESTATE_TUNED; | 564 | fepriv->state = FESTATE_TUNED; |
558 | } | 565 | } |
559 | 566 | ||
560 | fe->ops->tune(fe, params, fepriv->tune_mode_flags, &fepriv->delay, &s); | 567 | fe->ops.tune(fe, params, fepriv->tune_mode_flags, &fepriv->delay, &s); |
561 | if (s != fepriv->status) { | 568 | if (s != fepriv->status) { |
562 | dvb_frontend_add_event(fe, s); | 569 | dvb_frontend_add_event(fe, s); |
563 | fepriv->status = s; | 570 | fepriv->status = s; |
@@ -569,10 +576,15 @@ static int dvb_frontend_thread(void *data) | |||
569 | 576 | ||
570 | if (dvb_shutdown_timeout) { | 577 | if (dvb_shutdown_timeout) { |
571 | if (dvb_powerdown_on_sleep) | 578 | if (dvb_powerdown_on_sleep) |
572 | if (fe->ops->set_voltage) | 579 | if (fe->ops.set_voltage) |
573 | fe->ops->set_voltage(fe, SEC_VOLTAGE_OFF); | 580 | fe->ops.set_voltage(fe, SEC_VOLTAGE_OFF); |
574 | if (fe->ops->sleep) | 581 | if (fe->ops.tuner_ops.sleep) { |
575 | fe->ops->sleep(fe); | 582 | fe->ops.tuner_ops.sleep(fe); |
583 | if (fe->ops.i2c_gate_ctrl) | ||
584 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
585 | } | ||
586 | if (fe->ops.sleep) | ||
587 | fe->ops.sleep(fe); | ||
576 | } | 588 | } |
577 | 589 | ||
578 | fepriv->thread_pid = 0; | 590 | fepriv->thread_pid = 0; |
@@ -724,7 +736,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
724 | switch (cmd) { | 736 | switch (cmd) { |
725 | case FE_GET_INFO: { | 737 | case FE_GET_INFO: { |
726 | struct dvb_frontend_info* info = parg; | 738 | struct dvb_frontend_info* info = parg; |
727 | memcpy(info, &fe->ops->info, sizeof(struct dvb_frontend_info)); | 739 | memcpy(info, &fe->ops.info, sizeof(struct dvb_frontend_info)); |
728 | 740 | ||
729 | /* Force the CAN_INVERSION_AUTO bit on. If the frontend doesn't | 741 | /* Force the CAN_INVERSION_AUTO bit on. If the frontend doesn't |
730 | * do it, it is done for it. */ | 742 | * do it, it is done for it. */ |
@@ -744,58 +756,58 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
744 | break; | 756 | break; |
745 | } | 757 | } |
746 | 758 | ||
747 | if (fe->ops->read_status) | 759 | if (fe->ops.read_status) |
748 | err = fe->ops->read_status(fe, status); | 760 | err = fe->ops.read_status(fe, status); |
749 | break; | 761 | break; |
750 | } | 762 | } |
751 | case FE_READ_BER: | 763 | case FE_READ_BER: |
752 | if (fe->ops->read_ber) | 764 | if (fe->ops.read_ber) |
753 | err = fe->ops->read_ber(fe, (__u32*) parg); | 765 | err = fe->ops.read_ber(fe, (__u32*) parg); |
754 | break; | 766 | break; |
755 | 767 | ||
756 | case FE_READ_SIGNAL_STRENGTH: | 768 | case FE_READ_SIGNAL_STRENGTH: |
757 | if (fe->ops->read_signal_strength) | 769 | if (fe->ops.read_signal_strength) |
758 | err = fe->ops->read_signal_strength(fe, (__u16*) parg); | 770 | err = fe->ops.read_signal_strength(fe, (__u16*) parg); |
759 | break; | 771 | break; |
760 | 772 | ||
761 | case FE_READ_SNR: | 773 | case FE_READ_SNR: |
762 | if (fe->ops->read_snr) | 774 | if (fe->ops.read_snr) |
763 | err = fe->ops->read_snr(fe, (__u16*) parg); | 775 | err = fe->ops.read_snr(fe, (__u16*) parg); |
764 | break; | 776 | break; |
765 | 777 | ||
766 | case FE_READ_UNCORRECTED_BLOCKS: | 778 | case FE_READ_UNCORRECTED_BLOCKS: |
767 | if (fe->ops->read_ucblocks) | 779 | if (fe->ops.read_ucblocks) |
768 | err = fe->ops->read_ucblocks(fe, (__u32*) parg); | 780 | err = fe->ops.read_ucblocks(fe, (__u32*) parg); |
769 | break; | 781 | break; |
770 | 782 | ||
771 | 783 | ||
772 | case FE_DISEQC_RESET_OVERLOAD: | 784 | case FE_DISEQC_RESET_OVERLOAD: |
773 | if (fe->ops->diseqc_reset_overload) { | 785 | if (fe->ops.diseqc_reset_overload) { |
774 | err = fe->ops->diseqc_reset_overload(fe); | 786 | err = fe->ops.diseqc_reset_overload(fe); |
775 | fepriv->state = FESTATE_DISEQC; | 787 | fepriv->state = FESTATE_DISEQC; |
776 | fepriv->status = 0; | 788 | fepriv->status = 0; |
777 | } | 789 | } |
778 | break; | 790 | break; |
779 | 791 | ||
780 | case FE_DISEQC_SEND_MASTER_CMD: | 792 | case FE_DISEQC_SEND_MASTER_CMD: |
781 | if (fe->ops->diseqc_send_master_cmd) { | 793 | if (fe->ops.diseqc_send_master_cmd) { |
782 | err = fe->ops->diseqc_send_master_cmd(fe, (struct dvb_diseqc_master_cmd*) parg); | 794 | err = fe->ops.diseqc_send_master_cmd(fe, (struct dvb_diseqc_master_cmd*) parg); |
783 | fepriv->state = FESTATE_DISEQC; | 795 | fepriv->state = FESTATE_DISEQC; |
784 | fepriv->status = 0; | 796 | fepriv->status = 0; |
785 | } | 797 | } |
786 | break; | 798 | break; |
787 | 799 | ||
788 | case FE_DISEQC_SEND_BURST: | 800 | case FE_DISEQC_SEND_BURST: |
789 | if (fe->ops->diseqc_send_burst) { | 801 | if (fe->ops.diseqc_send_burst) { |
790 | err = fe->ops->diseqc_send_burst(fe, (fe_sec_mini_cmd_t) parg); | 802 | err = fe->ops.diseqc_send_burst(fe, (fe_sec_mini_cmd_t) parg); |
791 | fepriv->state = FESTATE_DISEQC; | 803 | fepriv->state = FESTATE_DISEQC; |
792 | fepriv->status = 0; | 804 | fepriv->status = 0; |
793 | } | 805 | } |
794 | break; | 806 | break; |
795 | 807 | ||
796 | case FE_SET_TONE: | 808 | case FE_SET_TONE: |
797 | if (fe->ops->set_tone) { | 809 | if (fe->ops.set_tone) { |
798 | err = fe->ops->set_tone(fe, (fe_sec_tone_mode_t) parg); | 810 | err = fe->ops.set_tone(fe, (fe_sec_tone_mode_t) parg); |
799 | fepriv->tone = (fe_sec_tone_mode_t) parg; | 811 | fepriv->tone = (fe_sec_tone_mode_t) parg; |
800 | fepriv->state = FESTATE_DISEQC; | 812 | fepriv->state = FESTATE_DISEQC; |
801 | fepriv->status = 0; | 813 | fepriv->status = 0; |
@@ -803,8 +815,8 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
803 | break; | 815 | break; |
804 | 816 | ||
805 | case FE_SET_VOLTAGE: | 817 | case FE_SET_VOLTAGE: |
806 | if (fe->ops->set_voltage) { | 818 | if (fe->ops.set_voltage) { |
807 | err = fe->ops->set_voltage(fe, (fe_sec_voltage_t) parg); | 819 | err = fe->ops.set_voltage(fe, (fe_sec_voltage_t) parg); |
808 | fepriv->voltage = (fe_sec_voltage_t) parg; | 820 | fepriv->voltage = (fe_sec_voltage_t) parg; |
809 | fepriv->state = FESTATE_DISEQC; | 821 | fepriv->state = FESTATE_DISEQC; |
810 | fepriv->status = 0; | 822 | fepriv->status = 0; |
@@ -812,11 +824,11 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
812 | break; | 824 | break; |
813 | 825 | ||
814 | case FE_DISHNETWORK_SEND_LEGACY_CMD: | 826 | case FE_DISHNETWORK_SEND_LEGACY_CMD: |
815 | if (fe->ops->dishnetwork_send_legacy_command) { | 827 | if (fe->ops.dishnetwork_send_legacy_command) { |
816 | err = fe->ops->dishnetwork_send_legacy_command(fe, (unsigned long) parg); | 828 | err = fe->ops.dishnetwork_send_legacy_command(fe, (unsigned long) parg); |
817 | fepriv->state = FESTATE_DISEQC; | 829 | fepriv->state = FESTATE_DISEQC; |
818 | fepriv->status = 0; | 830 | fepriv->status = 0; |
819 | } else if (fe->ops->set_voltage) { | 831 | } else if (fe->ops.set_voltage) { |
820 | /* | 832 | /* |
821 | * NOTE: This is a fallback condition. Some frontends | 833 | * NOTE: This is a fallback condition. Some frontends |
822 | * (stv0299 for instance) take longer than 8msec to | 834 | * (stv0299 for instance) take longer than 8msec to |
@@ -846,7 +858,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
846 | /* before sending a command, initialize by sending | 858 | /* before sending a command, initialize by sending |
847 | * a 32ms 18V to the switch | 859 | * a 32ms 18V to the switch |
848 | */ | 860 | */ |
849 | fe->ops->set_voltage(fe, SEC_VOLTAGE_18); | 861 | fe->ops.set_voltage(fe, SEC_VOLTAGE_18); |
850 | dvb_frontend_sleep_until(&nexttime, 32000); | 862 | dvb_frontend_sleep_until(&nexttime, 32000); |
851 | 863 | ||
852 | for (i = 0; i < 9; i++) { | 864 | for (i = 0; i < 9; i++) { |
@@ -854,7 +866,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
854 | do_gettimeofday(&tv[i + 1]); | 866 | do_gettimeofday(&tv[i + 1]); |
855 | if ((cmd & 0x01) != last) { | 867 | if ((cmd & 0x01) != last) { |
856 | /* set voltage to (last ? 13V : 18V) */ | 868 | /* set voltage to (last ? 13V : 18V) */ |
857 | fe->ops->set_voltage(fe, (last) ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18); | 869 | fe->ops.set_voltage(fe, (last) ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18); |
858 | last = (last) ? 0 : 1; | 870 | last = (last) ? 0 : 1; |
859 | } | 871 | } |
860 | cmd = cmd >> 1; | 872 | cmd = cmd >> 1; |
@@ -874,13 +886,13 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
874 | break; | 886 | break; |
875 | 887 | ||
876 | case FE_DISEQC_RECV_SLAVE_REPLY: | 888 | case FE_DISEQC_RECV_SLAVE_REPLY: |
877 | if (fe->ops->diseqc_recv_slave_reply) | 889 | if (fe->ops.diseqc_recv_slave_reply) |
878 | err = fe->ops->diseqc_recv_slave_reply(fe, (struct dvb_diseqc_slave_reply*) parg); | 890 | err = fe->ops.diseqc_recv_slave_reply(fe, (struct dvb_diseqc_slave_reply*) parg); |
879 | break; | 891 | break; |
880 | 892 | ||
881 | case FE_ENABLE_HIGH_LNB_VOLTAGE: | 893 | case FE_ENABLE_HIGH_LNB_VOLTAGE: |
882 | if (fe->ops->enable_high_lnb_voltage) | 894 | if (fe->ops.enable_high_lnb_voltage) |
883 | err = fe->ops->enable_high_lnb_voltage(fe, (long) parg); | 895 | err = fe->ops.enable_high_lnb_voltage(fe, (long) parg); |
884 | break; | 896 | break; |
885 | 897 | ||
886 | case FE_SET_FRONTEND: { | 898 | case FE_SET_FRONTEND: { |
@@ -898,7 +910,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
898 | fepriv->parameters.inversion = INVERSION_AUTO; | 910 | fepriv->parameters.inversion = INVERSION_AUTO; |
899 | fetunesettings.parameters.inversion = INVERSION_AUTO; | 911 | fetunesettings.parameters.inversion = INVERSION_AUTO; |
900 | } | 912 | } |
901 | if (fe->ops->info.type == FE_OFDM) { | 913 | if (fe->ops.info.type == FE_OFDM) { |
902 | /* without hierachical coding code_rate_LP is irrelevant, | 914 | /* without hierachical coding code_rate_LP is irrelevant, |
903 | * so we tolerate the otherwise invalid FEC_NONE setting */ | 915 | * so we tolerate the otherwise invalid FEC_NONE setting */ |
904 | if (fepriv->parameters.u.ofdm.hierarchy_information == HIERARCHY_NONE && | 916 | if (fepriv->parameters.u.ofdm.hierarchy_information == HIERARCHY_NONE && |
@@ -907,13 +919,13 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
907 | } | 919 | } |
908 | 920 | ||
909 | /* get frontend-specific tuning settings */ | 921 | /* get frontend-specific tuning settings */ |
910 | if (fe->ops->get_tune_settings && (fe->ops->get_tune_settings(fe, &fetunesettings) == 0)) { | 922 | if (fe->ops.get_tune_settings && (fe->ops.get_tune_settings(fe, &fetunesettings) == 0)) { |
911 | fepriv->min_delay = (fetunesettings.min_delay_ms * HZ) / 1000; | 923 | fepriv->min_delay = (fetunesettings.min_delay_ms * HZ) / 1000; |
912 | fepriv->max_drift = fetunesettings.max_drift; | 924 | fepriv->max_drift = fetunesettings.max_drift; |
913 | fepriv->step_size = fetunesettings.step_size; | 925 | fepriv->step_size = fetunesettings.step_size; |
914 | } else { | 926 | } else { |
915 | /* default values */ | 927 | /* default values */ |
916 | switch(fe->ops->info.type) { | 928 | switch(fe->ops.info.type) { |
917 | case FE_QPSK: | 929 | case FE_QPSK: |
918 | fepriv->min_delay = HZ/20; | 930 | fepriv->min_delay = HZ/20; |
919 | fepriv->step_size = fepriv->parameters.u.qpsk.symbol_rate / 16000; | 931 | fepriv->step_size = fepriv->parameters.u.qpsk.symbol_rate / 16000; |
@@ -928,11 +940,13 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
928 | 940 | ||
929 | case FE_OFDM: | 941 | case FE_OFDM: |
930 | fepriv->min_delay = HZ/20; | 942 | fepriv->min_delay = HZ/20; |
931 | fepriv->step_size = fe->ops->info.frequency_stepsize * 2; | 943 | fepriv->step_size = fe->ops.info.frequency_stepsize * 2; |
932 | fepriv->max_drift = (fe->ops->info.frequency_stepsize * 2) + 1; | 944 | fepriv->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1; |
933 | break; | 945 | break; |
934 | case FE_ATSC: | 946 | case FE_ATSC: |
935 | printk("dvb-core: FE_ATSC not handled yet.\n"); | 947 | fepriv->min_delay = HZ/20; |
948 | fepriv->step_size = 0; | ||
949 | fepriv->max_drift = 0; | ||
936 | break; | 950 | break; |
937 | } | 951 | } |
938 | } | 952 | } |
@@ -952,9 +966,9 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
952 | break; | 966 | break; |
953 | 967 | ||
954 | case FE_GET_FRONTEND: | 968 | case FE_GET_FRONTEND: |
955 | if (fe->ops->get_frontend) { | 969 | if (fe->ops.get_frontend) { |
956 | memcpy (parg, &fepriv->parameters, sizeof (struct dvb_frontend_parameters)); | 970 | memcpy (parg, &fepriv->parameters, sizeof (struct dvb_frontend_parameters)); |
957 | err = fe->ops->get_frontend(fe, (struct dvb_frontend_parameters*) parg); | 971 | err = fe->ops.get_frontend(fe, (struct dvb_frontend_parameters*) parg); |
958 | } | 972 | } |
959 | break; | 973 | break; |
960 | 974 | ||
@@ -1067,7 +1081,7 @@ int dvb_register_frontend(struct dvb_adapter* dvb, | |||
1067 | 1081 | ||
1068 | printk ("DVB: registering frontend %i (%s)...\n", | 1082 | printk ("DVB: registering frontend %i (%s)...\n", |
1069 | fe->dvb->num, | 1083 | fe->dvb->num, |
1070 | fe->ops->info.name); | 1084 | fe->ops.info.name); |
1071 | 1085 | ||
1072 | dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template, | 1086 | dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template, |
1073 | fe, DVB_DEVICE_FRONTEND); | 1087 | fe, DVB_DEVICE_FRONTEND); |
@@ -1085,10 +1099,15 @@ int dvb_unregister_frontend(struct dvb_frontend* fe) | |||
1085 | mutex_lock(&frontend_mutex); | 1099 | mutex_lock(&frontend_mutex); |
1086 | dvb_unregister_device (fepriv->dvbdev); | 1100 | dvb_unregister_device (fepriv->dvbdev); |
1087 | dvb_frontend_stop (fe); | 1101 | dvb_frontend_stop (fe); |
1088 | if (fe->ops->release) | 1102 | if (fe->ops.tuner_ops.release) { |
1089 | fe->ops->release(fe); | 1103 | fe->ops.tuner_ops.release(fe); |
1104 | if (fe->ops.i2c_gate_ctrl) | ||
1105 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
1106 | } | ||
1107 | if (fe->ops.release) | ||
1108 | fe->ops.release(fe); | ||
1090 | else | 1109 | else |
1091 | printk("dvb_frontend: Demodulator (%s) does not have a release callback!\n", fe->ops->info.name); | 1110 | printk("dvb_frontend: Demodulator (%s) does not have a release callback!\n", fe->ops.info.name); |
1092 | /* fe is invalid now */ | 1111 | /* fe is invalid now */ |
1093 | kfree(fepriv); | 1112 | kfree(fepriv); |
1094 | mutex_unlock(&frontend_mutex); | 1113 | mutex_unlock(&frontend_mutex); |
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h index 5926a3b745c9..2887e2b862a4 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/drivers/media/dvb/dvb-core/dvb_frontend.h | |||
@@ -49,6 +49,44 @@ struct dvb_frontend_tune_settings { | |||
49 | 49 | ||
50 | struct dvb_frontend; | 50 | struct dvb_frontend; |
51 | 51 | ||
52 | struct dvb_tuner_info { | ||
53 | char name[128]; | ||
54 | |||
55 | u32 frequency_min; | ||
56 | u32 frequency_max; | ||
57 | u32 frequency_step; | ||
58 | |||
59 | u32 bandwidth_min; | ||
60 | u32 bandwidth_max; | ||
61 | u32 bandwidth_step; | ||
62 | }; | ||
63 | |||
64 | struct dvb_tuner_ops { | ||
65 | |||
66 | struct dvb_tuner_info info; | ||
67 | |||
68 | int (*release)(struct dvb_frontend *fe); | ||
69 | int (*init)(struct dvb_frontend *fe); | ||
70 | int (*sleep)(struct dvb_frontend *fe); | ||
71 | |||
72 | /** This is for simple PLLs - set all parameters in one go. */ | ||
73 | int (*set_params)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p); | ||
74 | |||
75 | /** This is support for demods like the mt352 - fills out the supplied buffer with what to write. */ | ||
76 | int (*calc_regs)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p, u8 *buf, int buf_len); | ||
77 | |||
78 | int (*get_frequency)(struct dvb_frontend *fe, u32 *frequency); | ||
79 | int (*get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth); | ||
80 | |||
81 | #define TUNER_STATUS_LOCKED 1 | ||
82 | int (*get_status)(struct dvb_frontend *fe, u32 *status); | ||
83 | |||
84 | /** These are provided seperately from set_params in order to facilitate silicon | ||
85 | * tuners which require sophisticated tuning loops, controlling each parameter seperately. */ | ||
86 | int (*set_frequency)(struct dvb_frontend *fe, u32 frequency); | ||
87 | int (*set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth); | ||
88 | }; | ||
89 | |||
52 | struct dvb_frontend_ops { | 90 | struct dvb_frontend_ops { |
53 | 91 | ||
54 | struct dvb_frontend_info info; | 92 | struct dvb_frontend_info info; |
@@ -64,6 +102,8 @@ struct dvb_frontend_ops { | |||
64 | unsigned int mode_flags, | 102 | unsigned int mode_flags, |
65 | int *delay, | 103 | int *delay, |
66 | fe_status_t *status); | 104 | fe_status_t *status); |
105 | /* get frontend tuning algorithm from the module */ | ||
106 | int (*get_frontend_algo)(struct dvb_frontend *fe); | ||
67 | 107 | ||
68 | /* these two are only used for the swzigzag code */ | 108 | /* these two are only used for the swzigzag code */ |
69 | int (*set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | 109 | int (*set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); |
@@ -86,6 +126,8 @@ struct dvb_frontend_ops { | |||
86 | int (*enable_high_lnb_voltage)(struct dvb_frontend* fe, long arg); | 126 | int (*enable_high_lnb_voltage)(struct dvb_frontend* fe, long arg); |
87 | int (*dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned long cmd); | 127 | int (*dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned long cmd); |
88 | int (*i2c_gate_ctrl)(struct dvb_frontend* fe, int enable); | 128 | int (*i2c_gate_ctrl)(struct dvb_frontend* fe, int enable); |
129 | |||
130 | struct dvb_tuner_ops tuner_ops; | ||
89 | }; | 131 | }; |
90 | 132 | ||
91 | #define MAX_EVENT 8 | 133 | #define MAX_EVENT 8 |
@@ -100,9 +142,10 @@ struct dvb_fe_events { | |||
100 | }; | 142 | }; |
101 | 143 | ||
102 | struct dvb_frontend { | 144 | struct dvb_frontend { |
103 | struct dvb_frontend_ops* ops; | 145 | struct dvb_frontend_ops ops; |
104 | struct dvb_adapter *dvb; | 146 | struct dvb_adapter *dvb; |
105 | void* demodulator_priv; | 147 | void* demodulator_priv; |
148 | void* tuner_priv; | ||
106 | void* frontend_priv; | 149 | void* frontend_priv; |
107 | void* misc_priv; | 150 | void* misc_priv; |
108 | }; | 151 | }; |
diff --git a/drivers/media/dvb/dvb-core/dvb_math.c b/drivers/media/dvb/dvb-core/dvb_math.c new file mode 100644 index 000000000000..beb7c93aa6cb --- /dev/null +++ b/drivers/media/dvb/dvb-core/dvb_math.c | |||
@@ -0,0 +1,145 @@ | |||
1 | /* | ||
2 | * dvb-math provides some complex fixed-point math | ||
3 | * operations shared between the dvb related stuff | ||
4 | * | ||
5 | * Copyright (C) 2006 Christoph Pfister (christophpfister@gmail.com) | ||
6 | * | ||
7 | * This library is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU Lesser General Public License as | ||
9 | * published by the Free Software Foundation; either version 2.1 of | ||
10 | * the License, or (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public | ||
18 | * License along with this library; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #include <linux/bitops.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <asm/bug.h> | ||
26 | #include "dvb_math.h" | ||
27 | |||
28 | static const unsigned short logtable[256] = { | ||
29 | 0x0000, 0x0171, 0x02e0, 0x044e, 0x05ba, 0x0725, 0x088e, 0x09f7, | ||
30 | 0x0b5d, 0x0cc3, 0x0e27, 0x0f8a, 0x10eb, 0x124b, 0x13aa, 0x1508, | ||
31 | 0x1664, 0x17bf, 0x1919, 0x1a71, 0x1bc8, 0x1d1e, 0x1e73, 0x1fc6, | ||
32 | 0x2119, 0x226a, 0x23ba, 0x2508, 0x2656, 0x27a2, 0x28ed, 0x2a37, | ||
33 | 0x2b80, 0x2cc8, 0x2e0f, 0x2f54, 0x3098, 0x31dc, 0x331e, 0x345f, | ||
34 | 0x359f, 0x36de, 0x381b, 0x3958, 0x3a94, 0x3bce, 0x3d08, 0x3e41, | ||
35 | 0x3f78, 0x40af, 0x41e4, 0x4319, 0x444c, 0x457f, 0x46b0, 0x47e1, | ||
36 | 0x4910, 0x4a3f, 0x4b6c, 0x4c99, 0x4dc5, 0x4eef, 0x5019, 0x5142, | ||
37 | 0x526a, 0x5391, 0x54b7, 0x55dc, 0x5700, 0x5824, 0x5946, 0x5a68, | ||
38 | 0x5b89, 0x5ca8, 0x5dc7, 0x5ee5, 0x6003, 0x611f, 0x623a, 0x6355, | ||
39 | 0x646f, 0x6588, 0x66a0, 0x67b7, 0x68ce, 0x69e4, 0x6af8, 0x6c0c, | ||
40 | 0x6d20, 0x6e32, 0x6f44, 0x7055, 0x7165, 0x7274, 0x7383, 0x7490, | ||
41 | 0x759d, 0x76aa, 0x77b5, 0x78c0, 0x79ca, 0x7ad3, 0x7bdb, 0x7ce3, | ||
42 | 0x7dea, 0x7ef0, 0x7ff6, 0x80fb, 0x81ff, 0x8302, 0x8405, 0x8507, | ||
43 | 0x8608, 0x8709, 0x8809, 0x8908, 0x8a06, 0x8b04, 0x8c01, 0x8cfe, | ||
44 | 0x8dfa, 0x8ef5, 0x8fef, 0x90e9, 0x91e2, 0x92db, 0x93d2, 0x94ca, | ||
45 | 0x95c0, 0x96b6, 0x97ab, 0x98a0, 0x9994, 0x9a87, 0x9b7a, 0x9c6c, | ||
46 | 0x9d5e, 0x9e4f, 0x9f3f, 0xa02e, 0xa11e, 0xa20c, 0xa2fa, 0xa3e7, | ||
47 | 0xa4d4, 0xa5c0, 0xa6ab, 0xa796, 0xa881, 0xa96a, 0xaa53, 0xab3c, | ||
48 | 0xac24, 0xad0c, 0xadf2, 0xaed9, 0xafbe, 0xb0a4, 0xb188, 0xb26c, | ||
49 | 0xb350, 0xb433, 0xb515, 0xb5f7, 0xb6d9, 0xb7ba, 0xb89a, 0xb97a, | ||
50 | 0xba59, 0xbb38, 0xbc16, 0xbcf4, 0xbdd1, 0xbead, 0xbf8a, 0xc065, | ||
51 | 0xc140, 0xc21b, 0xc2f5, 0xc3cf, 0xc4a8, 0xc580, 0xc658, 0xc730, | ||
52 | 0xc807, 0xc8de, 0xc9b4, 0xca8a, 0xcb5f, 0xcc34, 0xcd08, 0xcddc, | ||
53 | 0xceaf, 0xcf82, 0xd054, 0xd126, 0xd1f7, 0xd2c8, 0xd399, 0xd469, | ||
54 | 0xd538, 0xd607, 0xd6d6, 0xd7a4, 0xd872, 0xd93f, 0xda0c, 0xdad9, | ||
55 | 0xdba5, 0xdc70, 0xdd3b, 0xde06, 0xded0, 0xdf9a, 0xe063, 0xe12c, | ||
56 | 0xe1f5, 0xe2bd, 0xe385, 0xe44c, 0xe513, 0xe5d9, 0xe69f, 0xe765, | ||
57 | 0xe82a, 0xe8ef, 0xe9b3, 0xea77, 0xeb3b, 0xebfe, 0xecc1, 0xed83, | ||
58 | 0xee45, 0xef06, 0xefc8, 0xf088, 0xf149, 0xf209, 0xf2c8, 0xf387, | ||
59 | 0xf446, 0xf505, 0xf5c3, 0xf680, 0xf73e, 0xf7fb, 0xf8b7, 0xf973, | ||
60 | 0xfa2f, 0xfaea, 0xfba5, 0xfc60, 0xfd1a, 0xfdd4, 0xfe8e, 0xff47 | ||
61 | }; | ||
62 | |||
63 | unsigned int intlog2(u32 value) | ||
64 | { | ||
65 | /** | ||
66 | * returns: log2(value) * 2^24 | ||
67 | * wrong result if value = 0 (log2(0) is undefined) | ||
68 | */ | ||
69 | unsigned int msb; | ||
70 | unsigned int logentry; | ||
71 | unsigned int significand; | ||
72 | unsigned int interpolation; | ||
73 | |||
74 | if (unlikely(value == 0)) { | ||
75 | WARN_ON(1); | ||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | /* first detect the msb (count begins at 0) */ | ||
80 | msb = fls(value) - 1; | ||
81 | |||
82 | /** | ||
83 | * now we use a logtable after the following method: | ||
84 | * | ||
85 | * log2(2^x * y) * 2^24 = x * 2^24 + log2(y) * 2^24 | ||
86 | * where x = msb and therefore 1 <= y < 2 | ||
87 | * first y is determined by shifting the value left | ||
88 | * so that msb is bit 31 | ||
89 | * 0x00231f56 -> 0x8C7D5800 | ||
90 | * the result is y * 2^31 -> "significand" | ||
91 | * then the highest 9 bits are used for a table lookup | ||
92 | * the highest bit is discarded because it's always set | ||
93 | * the highest nine bits in our example are 100011000 | ||
94 | * so we would use the entry 0x18 | ||
95 | */ | ||
96 | significand = value << (31 - msb); | ||
97 | logentry = (significand >> 23) & 0xff; | ||
98 | |||
99 | /** | ||
100 | * last step we do is interpolation because of the | ||
101 | * limitations of the log table the error is that part of | ||
102 | * the significand which isn't used for lookup then we | ||
103 | * compute the ratio between the error and the next table entry | ||
104 | * and interpolate it between the log table entry used and the | ||
105 | * next one the biggest error possible is 0x7fffff | ||
106 | * (in our example it's 0x7D5800) | ||
107 | * needed value for next table entry is 0x800000 | ||
108 | * so the interpolation is | ||
109 | * (error / 0x800000) * (logtable_next - logtable_current) | ||
110 | * in the implementation the division is moved to the end for | ||
111 | * better accuracy there is also an overflow correction if | ||
112 | * logtable_next is 256 | ||
113 | */ | ||
114 | interpolation = ((significand & 0x7fffff) * | ||
115 | ((logtable[(logentry + 1) & 0xff] - | ||
116 | logtable[logentry]) & 0xffff)) >> 15; | ||
117 | |||
118 | /* now we return the result */ | ||
119 | return ((msb << 24) + (logtable[logentry] << 8) + interpolation); | ||
120 | } | ||
121 | EXPORT_SYMBOL(intlog2); | ||
122 | |||
123 | unsigned int intlog10(u32 value) | ||
124 | { | ||
125 | /** | ||
126 | * returns: log10(value) * 2^24 | ||
127 | * wrong result if value = 0 (log10(0) is undefined) | ||
128 | */ | ||
129 | u64 log; | ||
130 | |||
131 | if (unlikely(value == 0)) { | ||
132 | WARN_ON(1); | ||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | log = intlog2(value); | ||
137 | |||
138 | /** | ||
139 | * we use the following method: | ||
140 | * log10(x) = log2(x) * log10(2) | ||
141 | */ | ||
142 | |||
143 | return (log * 646456993) >> 31; | ||
144 | } | ||
145 | EXPORT_SYMBOL(intlog10); | ||
diff --git a/drivers/media/dvb/dvb-core/dvb_math.h b/drivers/media/dvb/dvb-core/dvb_math.h new file mode 100644 index 000000000000..aecc867e9404 --- /dev/null +++ b/drivers/media/dvb/dvb-core/dvb_math.h | |||
@@ -0,0 +1,58 @@ | |||
1 | /* | ||
2 | * dvb-math provides some complex fixed-point math | ||
3 | * operations shared between the dvb related stuff | ||
4 | * | ||
5 | * Copyright (C) 2006 Christoph Pfister (christophpfister@gmail.com) | ||
6 | * | ||
7 | * This library is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU Lesser General Public License as | ||
9 | * published by the Free Software Foundation; either version 2.1 of | ||
10 | * the License, or (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public | ||
18 | * License along with this library; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #ifndef __DVB_MATH_H | ||
23 | #define __DVB_MATH_H | ||
24 | |||
25 | #include <linux/types.h> | ||
26 | |||
27 | /** | ||
28 | * computes log2 of a value; the result is shifted left by 24 bits | ||
29 | * | ||
30 | * to use rational values you can use the following method: | ||
31 | * intlog2(value) = intlog2(value * 2^x) - x * 2^24 | ||
32 | * | ||
33 | * example: intlog2(8) will give 3 << 24 = 3 * 2^24 | ||
34 | * example: intlog2(9) will give 3 << 24 + ... = 3.16... * 2^24 | ||
35 | * example: intlog2(1.5) = intlog2(3) - 2^24 = 0.584... * 2^24 | ||
36 | * | ||
37 | * @param value The value (must be != 0) | ||
38 | * @return log2(value) * 2^24 | ||
39 | */ | ||
40 | extern unsigned int intlog2(u32 value); | ||
41 | |||
42 | /** | ||
43 | * computes log10 of a value; the result is shifted left by 24 bits | ||
44 | * | ||
45 | * to use rational values you can use the following method: | ||
46 | * intlog10(value) = intlog10(value * 10^x) - x * 2^24 | ||
47 | * | ||
48 | * example: intlog10(1000) will give 3 << 24 = 3 * 2^24 | ||
49 | * due to the implementation intlog10(1000) might be not exactly 3 * 2^24 | ||
50 | * | ||
51 | * look at intlog2 for similar examples | ||
52 | * | ||
53 | * @param value The value (must be != 0) | ||
54 | * @return log10(value) * 2^24 | ||
55 | */ | ||
56 | extern unsigned int intlog10(u32 value); | ||
57 | |||
58 | #endif | ||
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c index 9fd87521a163..8859ab74f0fe 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.c +++ b/drivers/media/dvb/dvb-core/dvb_net.c | |||
@@ -12,7 +12,7 @@ | |||
12 | * Hilmar Linder <hlinder@cosy.sbg.ac.at> | 12 | * Hilmar Linder <hlinder@cosy.sbg.ac.at> |
13 | * and Wolfram Stering <wstering@cosy.sbg.ac.at> | 13 | * and Wolfram Stering <wstering@cosy.sbg.ac.at> |
14 | * | 14 | * |
15 | * ULE Decaps according to draft-ietf-ipdvb-ule-03.txt. | 15 | * ULE Decaps according to RFC 4326. |
16 | * | 16 | * |
17 | * This program is free software; you can redistribute it and/or | 17 | * This program is free software; you can redistribute it and/or |
18 | * modify it under the terms of the GNU General Public License | 18 | * modify it under the terms of the GNU General Public License |
@@ -42,6 +42,9 @@ | |||
42 | * Bugfixes and robustness improvements. | 42 | * Bugfixes and robustness improvements. |
43 | * Filtering on dest MAC addresses, if present (D-Bit = 0) | 43 | * Filtering on dest MAC addresses, if present (D-Bit = 0) |
44 | * ULE_DEBUG compile-time option. | 44 | * ULE_DEBUG compile-time option. |
45 | * Apr 2006: cp v3: Bugfixes and compliency with RFC 4326 (ULE) by | ||
46 | * Christian Praehauser <cpraehaus@cosy.sbg.ac.at>, | ||
47 | * Paris Lodron University of Salzburg. | ||
45 | */ | 48 | */ |
46 | 49 | ||
47 | /* | 50 | /* |
@@ -49,9 +52,6 @@ | |||
49 | * | 52 | * |
50 | * Unloading does not work for 2.6.9 kernels: a refcount doesn't go to zero. | 53 | * Unloading does not work for 2.6.9 kernels: a refcount doesn't go to zero. |
51 | * | 54 | * |
52 | * TS_FEED callback is called once for every single TS cell although it is | ||
53 | * registered (in dvb_net_feed_start()) for 100 TS cells (used for dvb_net_ule()). | ||
54 | * | ||
55 | */ | 55 | */ |
56 | 56 | ||
57 | #include <linux/module.h> | 57 | #include <linux/module.h> |
@@ -89,6 +89,9 @@ static inline __u32 iov_crc32( __u32 c, struct kvec *iov, unsigned int cnt ) | |||
89 | 89 | ||
90 | #ifdef ULE_DEBUG | 90 | #ifdef ULE_DEBUG |
91 | 91 | ||
92 | #define MAC_ADDR_PRINTFMT "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x" | ||
93 | #define MAX_ADDR_PRINTFMT_ARGS(macap) (macap)[0],(macap)[1],(macap)[2],(macap)[3],(macap)[4],(macap)[5] | ||
94 | |||
92 | #define isprint(c) ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')) | 95 | #define isprint(c) ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')) |
93 | 96 | ||
94 | static void hexdump( const unsigned char *buf, unsigned short len ) | 97 | static void hexdump( const unsigned char *buf, unsigned short len ) |
@@ -214,6 +217,8 @@ static unsigned short dvb_net_eth_type_trans(struct sk_buff *skb, | |||
214 | #define ULE_TEST 0 | 217 | #define ULE_TEST 0 |
215 | #define ULE_BRIDGED 1 | 218 | #define ULE_BRIDGED 1 |
216 | 219 | ||
220 | #define ULE_OPTEXTHDR_PADDING 0 | ||
221 | |||
217 | static int ule_test_sndu( struct dvb_net_priv *p ) | 222 | static int ule_test_sndu( struct dvb_net_priv *p ) |
218 | { | 223 | { |
219 | return -1; | 224 | return -1; |
@@ -221,14 +226,28 @@ static int ule_test_sndu( struct dvb_net_priv *p ) | |||
221 | 226 | ||
222 | static int ule_bridged_sndu( struct dvb_net_priv *p ) | 227 | static int ule_bridged_sndu( struct dvb_net_priv *p ) |
223 | { | 228 | { |
224 | /* BRIDGE SNDU handling sucks in draft-ietf-ipdvb-ule-03.txt. | 229 | struct ethhdr *hdr = (struct ethhdr*) p->ule_next_hdr; |
225 | * This has to be the last extension header, otherwise it won't work. | 230 | if(ntohs(hdr->h_proto) < 1536) { |
226 | * Blame the authors! | 231 | int framelen = p->ule_sndu_len - ((p->ule_next_hdr+sizeof(struct ethhdr)) - p->ule_skb->data); |
232 | /* A frame Type < 1536 for a bridged frame, introduces a LLC Length field. */ | ||
233 | if(framelen != ntohs(hdr->h_proto)) { | ||
234 | return -1; | ||
235 | } | ||
236 | } | ||
237 | /* Note: | ||
238 | * From RFC4326: | ||
239 | * "A bridged SNDU is a Mandatory Extension Header of Type 1. | ||
240 | * It must be the final (or only) extension header specified in the header chain of a SNDU." | ||
241 | * The 'ule_bridged' flag will cause the extension header processing loop to terminate. | ||
227 | */ | 242 | */ |
228 | p->ule_bridged = 1; | 243 | p->ule_bridged = 1; |
229 | return 0; | 244 | return 0; |
230 | } | 245 | } |
231 | 246 | ||
247 | static int ule_exthdr_padding(struct dvb_net_priv *p) | ||
248 | { | ||
249 | return 0; | ||
250 | } | ||
232 | 251 | ||
233 | /** Handle ULE extension headers. | 252 | /** Handle ULE extension headers. |
234 | * Function is called after a successful CRC32 verification of an ULE SNDU to complete its decoding. | 253 | * Function is called after a successful CRC32 verification of an ULE SNDU to complete its decoding. |
@@ -242,7 +261,8 @@ static int handle_one_ule_extension( struct dvb_net_priv *p ) | |||
242 | { [0] = ule_test_sndu, [1] = ule_bridged_sndu, [2] = NULL, }; | 261 | { [0] = ule_test_sndu, [1] = ule_bridged_sndu, [2] = NULL, }; |
243 | 262 | ||
244 | /* Table of optional extension header handlers. The header type is the index. */ | 263 | /* Table of optional extension header handlers. The header type is the index. */ |
245 | static int (*ule_optional_ext_handlers[255])( struct dvb_net_priv *p ) = { NULL, }; | 264 | static int (*ule_optional_ext_handlers[255])( struct dvb_net_priv *p ) = |
265 | { [0] = ule_exthdr_padding, [1] = NULL, }; | ||
246 | 266 | ||
247 | int ext_len = 0; | 267 | int ext_len = 0; |
248 | unsigned char hlen = (p->ule_sndu_type & 0x0700) >> 8; | 268 | unsigned char hlen = (p->ule_sndu_type & 0x0700) >> 8; |
@@ -253,25 +273,31 @@ static int handle_one_ule_extension( struct dvb_net_priv *p ) | |||
253 | /* Mandatory extension header */ | 273 | /* Mandatory extension header */ |
254 | if (ule_mandatory_ext_handlers[htype]) { | 274 | if (ule_mandatory_ext_handlers[htype]) { |
255 | ext_len = ule_mandatory_ext_handlers[htype]( p ); | 275 | ext_len = ule_mandatory_ext_handlers[htype]( p ); |
256 | p->ule_next_hdr += ext_len; | 276 | if(ext_len >= 0) { |
257 | if (! p->ule_bridged) { | 277 | p->ule_next_hdr += ext_len; |
258 | p->ule_sndu_type = ntohs( *(unsigned short *)p->ule_next_hdr ); | 278 | if (!p->ule_bridged) { |
259 | p->ule_next_hdr += 2; | 279 | p->ule_sndu_type = ntohs(*(unsigned short *)p->ule_next_hdr); |
260 | } else { | 280 | p->ule_next_hdr += 2; |
261 | p->ule_sndu_type = ntohs( *(unsigned short *)(p->ule_next_hdr + ((p->ule_dbit ? 2 : 3) * ETH_ALEN)) ); | 281 | } else { |
262 | /* This assures the extension handling loop will terminate. */ | 282 | p->ule_sndu_type = ntohs(*(unsigned short *)(p->ule_next_hdr + ((p->ule_dbit ? 2 : 3) * ETH_ALEN))); |
283 | /* This assures the extension handling loop will terminate. */ | ||
284 | } | ||
263 | } | 285 | } |
286 | // else: extension handler failed or SNDU should be discarded | ||
264 | } else | 287 | } else |
265 | ext_len = -1; /* SNDU has to be discarded. */ | 288 | ext_len = -1; /* SNDU has to be discarded. */ |
266 | } else { | 289 | } else { |
267 | /* Optional extension header. Calculate the length. */ | 290 | /* Optional extension header. Calculate the length. */ |
268 | ext_len = hlen << 2; | 291 | ext_len = hlen << 1; |
269 | /* Process the optional extension header according to its type. */ | 292 | /* Process the optional extension header according to its type. */ |
270 | if (ule_optional_ext_handlers[htype]) | 293 | if (ule_optional_ext_handlers[htype]) |
271 | (void)ule_optional_ext_handlers[htype]( p ); | 294 | (void)ule_optional_ext_handlers[htype]( p ); |
272 | p->ule_next_hdr += ext_len; | 295 | p->ule_next_hdr += ext_len; |
273 | p->ule_sndu_type = ntohs( *(unsigned short *)p->ule_next_hdr ); | 296 | p->ule_sndu_type = ntohs( *(unsigned short *)(p->ule_next_hdr-2) ); |
274 | p->ule_next_hdr += 2; | 297 | /* |
298 | * note: the length of the next header type is included in the | ||
299 | * length of THIS optional extension header | ||
300 | */ | ||
275 | } | 301 | } |
276 | 302 | ||
277 | return ext_len; | 303 | return ext_len; |
@@ -284,8 +310,14 @@ static int handle_ule_extensions( struct dvb_net_priv *p ) | |||
284 | p->ule_next_hdr = p->ule_skb->data; | 310 | p->ule_next_hdr = p->ule_skb->data; |
285 | do { | 311 | do { |
286 | l = handle_one_ule_extension( p ); | 312 | l = handle_one_ule_extension( p ); |
287 | if (l == -1) return -1; /* Stop extension header processing and discard SNDU. */ | 313 | if (l < 0) |
314 | return l; /* Stop extension header processing and discard SNDU. */ | ||
288 | total_ext_len += l; | 315 | total_ext_len += l; |
316 | #ifdef ULE_DEBUG | ||
317 | dprintk("handle_ule_extensions: ule_next_hdr=%p, ule_sndu_type=%i, " | ||
318 | "l=%i, total_ext_len=%i\n", p->ule_next_hdr, | ||
319 | (int) p->ule_sndu_type, l, total_ext_len); | ||
320 | #endif | ||
289 | 321 | ||
290 | } while (p->ule_sndu_type < 1536); | 322 | } while (p->ule_sndu_type < 1536); |
291 | 323 | ||
@@ -355,8 +387,8 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) | |||
355 | if (priv->ule_skb) { | 387 | if (priv->ule_skb) { |
356 | dev_kfree_skb( priv->ule_skb ); | 388 | dev_kfree_skb( priv->ule_skb ); |
357 | /* Prepare for next SNDU. */ | 389 | /* Prepare for next SNDU. */ |
358 | ((struct dvb_net_priv *) dev->priv)->stats.rx_errors++; | 390 | priv->stats.rx_errors++; |
359 | ((struct dvb_net_priv *) dev->priv)->stats.rx_frame_errors++; | 391 | priv->stats.rx_frame_errors++; |
360 | } | 392 | } |
361 | reset_ule(priv); | 393 | reset_ule(priv); |
362 | priv->need_pusi = 1; | 394 | priv->need_pusi = 1; |
@@ -396,27 +428,25 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) | |||
396 | } | 428 | } |
397 | } | 429 | } |
398 | 430 | ||
399 | /* Check continuity counter. */ | ||
400 | if (new_ts) { | 431 | if (new_ts) { |
432 | /* Check continuity counter. */ | ||
401 | if ((ts[3] & 0x0F) == priv->tscc) | 433 | if ((ts[3] & 0x0F) == priv->tscc) |
402 | priv->tscc = (priv->tscc + 1) & 0x0F; | 434 | priv->tscc = (priv->tscc + 1) & 0x0F; |
403 | else { | 435 | else { |
404 | /* TS discontinuity handling: */ | 436 | /* TS discontinuity handling: */ |
405 | printk(KERN_WARNING "%lu: TS discontinuity: got %#x, " | 437 | printk(KERN_WARNING "%lu: TS discontinuity: got %#x, " |
406 | "exptected %#x.\n", priv->ts_count, ts[3] & 0x0F, priv->tscc); | 438 | "expected %#x.\n", priv->ts_count, ts[3] & 0x0F, priv->tscc); |
407 | /* Drop partly decoded SNDU, reset state, resync on PUSI. */ | 439 | /* Drop partly decoded SNDU, reset state, resync on PUSI. */ |
408 | if (priv->ule_skb) { | 440 | if (priv->ule_skb) { |
409 | dev_kfree_skb( priv->ule_skb ); | 441 | dev_kfree_skb( priv->ule_skb ); |
410 | /* Prepare for next SNDU. */ | 442 | /* Prepare for next SNDU. */ |
411 | // reset_ule(priv); moved to below. | 443 | // reset_ule(priv); moved to below. |
412 | ((struct dvb_net_priv *) dev->priv)->stats.rx_errors++; | 444 | priv->stats.rx_errors++; |
413 | ((struct dvb_net_priv *) dev->priv)->stats.rx_frame_errors++; | 445 | priv->stats.rx_frame_errors++; |
414 | } | 446 | } |
415 | reset_ule(priv); | 447 | reset_ule(priv); |
416 | /* skip to next PUSI. */ | 448 | /* skip to next PUSI. */ |
417 | priv->need_pusi = 1; | 449 | priv->need_pusi = 1; |
418 | ts += TS_SZ; | ||
419 | priv->ts_count++; | ||
420 | continue; | 450 | continue; |
421 | } | 451 | } |
422 | /* If we still have an incomplete payload, but PUSI is | 452 | /* If we still have an incomplete payload, but PUSI is |
@@ -425,7 +455,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) | |||
425 | * cells (continuity counter wrap). */ | 455 | * cells (continuity counter wrap). */ |
426 | if (ts[1] & TS_PUSI) { | 456 | if (ts[1] & TS_PUSI) { |
427 | if (! priv->need_pusi) { | 457 | if (! priv->need_pusi) { |
428 | if (*from_where > 181) { | 458 | if (!(*from_where < (ts_remain-1)) || *from_where != priv->ule_sndu_remain) { |
429 | /* Pointer field is invalid. Drop this TS cell and any started ULE SNDU. */ | 459 | /* Pointer field is invalid. Drop this TS cell and any started ULE SNDU. */ |
430 | printk(KERN_WARNING "%lu: Invalid pointer " | 460 | printk(KERN_WARNING "%lu: Invalid pointer " |
431 | "field: %u.\n", priv->ts_count, *from_where); | 461 | "field: %u.\n", priv->ts_count, *from_where); |
@@ -438,8 +468,6 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) | |||
438 | } | 468 | } |
439 | reset_ule(priv); | 469 | reset_ule(priv); |
440 | priv->need_pusi = 1; | 470 | priv->need_pusi = 1; |
441 | ts += TS_SZ; | ||
442 | priv->ts_count++; | ||
443 | continue; | 471 | continue; |
444 | } | 472 | } |
445 | /* Skip pointer field (we're processing a | 473 | /* Skip pointer field (we're processing a |
@@ -452,8 +480,8 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) | |||
452 | if (priv->ule_sndu_remain > 183) { | 480 | if (priv->ule_sndu_remain > 183) { |
453 | /* Current SNDU lacks more data than there could be available in the | 481 | /* Current SNDU lacks more data than there could be available in the |
454 | * current TS cell. */ | 482 | * current TS cell. */ |
455 | ((struct dvb_net_priv *) dev->priv)->stats.rx_errors++; | 483 | priv->stats.rx_errors++; |
456 | ((struct dvb_net_priv *) dev->priv)->stats.rx_length_errors++; | 484 | priv->stats.rx_length_errors++; |
457 | printk(KERN_WARNING "%lu: Expected %d more SNDU bytes, but " | 485 | printk(KERN_WARNING "%lu: Expected %d more SNDU bytes, but " |
458 | "got PUSI (pf %d, ts_remain %d). Flushing incomplete payload.\n", | 486 | "got PUSI (pf %d, ts_remain %d). Flushing incomplete payload.\n", |
459 | priv->ts_count, priv->ule_sndu_remain, ts[4], ts_remain); | 487 | priv->ts_count, priv->ule_sndu_remain, ts[4], ts_remain); |
@@ -492,9 +520,11 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) | |||
492 | } else | 520 | } else |
493 | priv->ule_dbit = 0; | 521 | priv->ule_dbit = 0; |
494 | 522 | ||
495 | if (priv->ule_sndu_len > 32763) { | 523 | if (priv->ule_sndu_len < 5) { |
496 | printk(KERN_WARNING "%lu: Invalid ULE SNDU length %u. " | 524 | printk(KERN_WARNING "%lu: Invalid ULE SNDU length %u. " |
497 | "Resyncing.\n", priv->ts_count, priv->ule_sndu_len); | 525 | "Resyncing.\n", priv->ts_count, priv->ule_sndu_len); |
526 | priv->stats.rx_errors++; | ||
527 | priv->stats.rx_length_errors++; | ||
498 | priv->ule_sndu_len = 0; | 528 | priv->ule_sndu_len = 0; |
499 | priv->need_pusi = 1; | 529 | priv->need_pusi = 1; |
500 | new_ts = 1; | 530 | new_ts = 1; |
@@ -608,58 +638,103 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) | |||
608 | ule_dump = 1; | 638 | ule_dump = 1; |
609 | #endif | 639 | #endif |
610 | 640 | ||
611 | ((struct dvb_net_priv *) dev->priv)->stats.rx_errors++; | 641 | priv->stats.rx_errors++; |
612 | ((struct dvb_net_priv *) dev->priv)->stats.rx_crc_errors++; | 642 | priv->stats.rx_crc_errors++; |
613 | dev_kfree_skb(priv->ule_skb); | 643 | dev_kfree_skb(priv->ule_skb); |
614 | } else { | 644 | } else { |
615 | /* CRC32 verified OK. */ | 645 | /* CRC32 verified OK. */ |
646 | u8 dest_addr[ETH_ALEN]; | ||
647 | static const u8 bc_addr[ETH_ALEN] = | ||
648 | { [ 0 ... ETH_ALEN-1] = 0xff }; | ||
649 | |||
650 | /* CRC32 was OK. Remove it from skb. */ | ||
651 | priv->ule_skb->tail -= 4; | ||
652 | priv->ule_skb->len -= 4; | ||
653 | |||
654 | if (!priv->ule_dbit) { | ||
655 | /* | ||
656 | * The destination MAC address is the | ||
657 | * next data in the skb. It comes | ||
658 | * before any extension headers. | ||
659 | * | ||
660 | * Check if the payload of this SNDU | ||
661 | * should be passed up the stack. | ||
662 | */ | ||
663 | register int drop = 0; | ||
664 | if (priv->rx_mode != RX_MODE_PROMISC) { | ||
665 | if (priv->ule_skb->data[0] & 0x01) { | ||
666 | /* multicast or broadcast */ | ||
667 | if (memcmp(priv->ule_skb->data, bc_addr, ETH_ALEN)) { | ||
668 | /* multicast */ | ||
669 | if (priv->rx_mode == RX_MODE_MULTI) { | ||
670 | int i; | ||
671 | for(i = 0; i < priv->multi_num && memcmp(priv->ule_skb->data, priv->multi_macs[i], ETH_ALEN); i++) | ||
672 | ; | ||
673 | if (i == priv->multi_num) | ||
674 | drop = 1; | ||
675 | } else if (priv->rx_mode != RX_MODE_ALL_MULTI) | ||
676 | drop = 1; /* no broadcast; */ | ||
677 | /* else: all multicast mode: accept all multicast packets */ | ||
678 | } | ||
679 | /* else: broadcast */ | ||
680 | } | ||
681 | else if (memcmp(priv->ule_skb->data, dev->dev_addr, ETH_ALEN)) | ||
682 | drop = 1; | ||
683 | /* else: destination address matches the MAC address of our receiver device */ | ||
684 | } | ||
685 | /* else: promiscious mode; pass everything up the stack */ | ||
686 | |||
687 | if (drop) { | ||
688 | #ifdef ULE_DEBUG | ||
689 | dprintk("Dropping SNDU: MAC destination address does not match: dest addr: "MAC_ADDR_PRINTFMT", dev addr: "MAC_ADDR_PRINTFMT"\n", | ||
690 | MAX_ADDR_PRINTFMT_ARGS(priv->ule_skb->data), MAX_ADDR_PRINTFMT_ARGS(dev->dev_addr)); | ||
691 | #endif | ||
692 | dev_kfree_skb(priv->ule_skb); | ||
693 | goto sndu_done; | ||
694 | } | ||
695 | else | ||
696 | { | ||
697 | memcpy(dest_addr, priv->ule_skb->data, ETH_ALEN); | ||
698 | skb_pull(priv->ule_skb, ETH_ALEN); | ||
699 | } | ||
700 | } | ||
701 | |||
616 | /* Handle ULE Extension Headers. */ | 702 | /* Handle ULE Extension Headers. */ |
617 | if (priv->ule_sndu_type < 1536) { | 703 | if (priv->ule_sndu_type < 1536) { |
618 | /* There is an extension header. Handle it accordingly. */ | 704 | /* There is an extension header. Handle it accordingly. */ |
619 | int l = handle_ule_extensions( priv ); | 705 | int l = handle_ule_extensions(priv); |
620 | if (l < 0) { | 706 | if (l < 0) { |
621 | /* Mandatory extension header unknown or TEST SNDU. Drop it. */ | 707 | /* Mandatory extension header unknown or TEST SNDU. Drop it. */ |
622 | // printk( KERN_WARNING "Dropping SNDU, extension headers.\n" ); | 708 | // printk( KERN_WARNING "Dropping SNDU, extension headers.\n" ); |
623 | dev_kfree_skb( priv->ule_skb ); | 709 | dev_kfree_skb(priv->ule_skb); |
624 | goto sndu_done; | 710 | goto sndu_done; |
625 | } | 711 | } |
626 | skb_pull( priv->ule_skb, l ); | 712 | skb_pull(priv->ule_skb, l); |
627 | } | 713 | } |
628 | 714 | ||
629 | /* CRC32 was OK. Remove it from skb. */ | 715 | /* |
630 | priv->ule_skb->tail -= 4; | 716 | * Construct/assure correct ethernet header. |
631 | priv->ule_skb->len -= 4; | 717 | * Note: in bridged mode (priv->ule_bridged != |
632 | 718 | * 0) we already have the (original) ethernet | |
633 | /* Filter on receiver's destination MAC address, if present. */ | 719 | * header at the start of the payload (after |
634 | if (!priv->ule_dbit) { | 720 | * optional dest. address and any extension |
635 | /* The destination MAC address is the next data in the skb. */ | 721 | * headers). |
636 | if (memcmp( priv->ule_skb->data, dev->dev_addr, ETH_ALEN )) { | 722 | */ |
637 | /* MAC addresses don't match. Drop SNDU. */ | 723 | |
638 | // printk( KERN_WARNING "Dropping SNDU, MAC address.\n" ); | 724 | if (!priv->ule_bridged) { |
639 | dev_kfree_skb( priv->ule_skb ); | 725 | skb_push(priv->ule_skb, ETH_HLEN); |
640 | goto sndu_done; | 726 | ethh = (struct ethhdr *)priv->ule_skb->data; |
641 | } | 727 | if (!priv->ule_dbit) { |
642 | if (! priv->ule_bridged) { | 728 | /* dest_addr buffer is only valid if priv->ule_dbit == 0 */ |
643 | skb_push( priv->ule_skb, ETH_ALEN + 2 ); | 729 | memcpy(ethh->h_dest, dest_addr, ETH_ALEN); |
644 | ethh = (struct ethhdr *)priv->ule_skb->data; | 730 | memset(ethh->h_source, 0, ETH_ALEN); |
645 | memcpy( ethh->h_dest, ethh->h_source, ETH_ALEN ); | ||
646 | memset( ethh->h_source, 0, ETH_ALEN ); | ||
647 | ethh->h_proto = htons( priv->ule_sndu_type ); | ||
648 | } else { | ||
649 | /* Skip the Receiver destination MAC address. */ | ||
650 | skb_pull( priv->ule_skb, ETH_ALEN ); | ||
651 | } | ||
652 | } else { | ||
653 | if (! priv->ule_bridged) { | ||
654 | skb_push( priv->ule_skb, ETH_HLEN ); | ||
655 | ethh = (struct ethhdr *)priv->ule_skb->data; | ||
656 | memcpy( ethh->h_dest, dev->dev_addr, ETH_ALEN ); | ||
657 | memset( ethh->h_source, 0, ETH_ALEN ); | ||
658 | ethh->h_proto = htons( priv->ule_sndu_type ); | ||
659 | } else { | ||
660 | /* skb is in correct state; nothing to do. */ | ||
661 | } | 731 | } |
732 | else /* zeroize source and dest */ | ||
733 | memset( ethh, 0, ETH_ALEN*2 ); | ||
734 | |||
735 | ethh->h_proto = htons(priv->ule_sndu_type); | ||
662 | } | 736 | } |
737 | /* else: skb is in correct state; nothing to do. */ | ||
663 | priv->ule_bridged = 0; | 738 | priv->ule_bridged = 0; |
664 | 739 | ||
665 | /* Stuff into kernel's protocol stack. */ | 740 | /* Stuff into kernel's protocol stack. */ |
@@ -668,8 +743,8 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) | |||
668 | * receive the packet anyhow. */ | 743 | * receive the packet anyhow. */ |
669 | /* if (priv->ule_dbit && skb->pkt_type == PACKET_OTHERHOST) | 744 | /* if (priv->ule_dbit && skb->pkt_type == PACKET_OTHERHOST) |
670 | priv->ule_skb->pkt_type = PACKET_HOST; */ | 745 | priv->ule_skb->pkt_type = PACKET_HOST; */ |
671 | ((struct dvb_net_priv *) dev->priv)->stats.rx_packets++; | 746 | priv->stats.rx_packets++; |
672 | ((struct dvb_net_priv *) dev->priv)->stats.rx_bytes += priv->ule_skb->len; | 747 | priv->stats.rx_bytes += priv->ule_skb->len; |
673 | netif_rx(priv->ule_skb); | 748 | netif_rx(priv->ule_skb); |
674 | } | 749 | } |
675 | sndu_done: | 750 | sndu_done: |
@@ -944,7 +1019,7 @@ static int dvb_net_feed_start(struct net_device *dev) | |||
944 | dprintk("%s: start filtering\n", __FUNCTION__); | 1019 | dprintk("%s: start filtering\n", __FUNCTION__); |
945 | priv->secfeed->start_filtering(priv->secfeed); | 1020 | priv->secfeed->start_filtering(priv->secfeed); |
946 | } else if (priv->feedtype == DVB_NET_FEEDTYPE_ULE) { | 1021 | } else if (priv->feedtype == DVB_NET_FEEDTYPE_ULE) { |
947 | struct timespec timeout = { 0, 30000000 }; // 30 msec | 1022 | struct timespec timeout = { 0, 10000000 }; // 10 msec |
948 | 1023 | ||
949 | /* we have payloads encapsulated in TS */ | 1024 | /* we have payloads encapsulated in TS */ |
950 | dprintk("%s: alloc tsfeed\n", __FUNCTION__); | 1025 | dprintk("%s: alloc tsfeed\n", __FUNCTION__); |
@@ -956,10 +1031,13 @@ static int dvb_net_feed_start(struct net_device *dev) | |||
956 | 1031 | ||
957 | /* Set netdevice pointer for ts decaps callback. */ | 1032 | /* Set netdevice pointer for ts decaps callback. */ |
958 | priv->tsfeed->priv = (void *)dev; | 1033 | priv->tsfeed->priv = (void *)dev; |
959 | ret = priv->tsfeed->set(priv->tsfeed, priv->pid, | 1034 | ret = priv->tsfeed->set(priv->tsfeed, |
960 | TS_PACKET, DMX_TS_PES_OTHER, | 1035 | priv->pid, /* pid */ |
1036 | TS_PACKET, /* type */ | ||
1037 | DMX_TS_PES_OTHER, /* pes type */ | ||
961 | 32768, /* circular buffer size */ | 1038 | 32768, /* circular buffer size */ |
962 | timeout); | 1039 | timeout /* timeout */ |
1040 | ); | ||
963 | 1041 | ||
964 | if (ret < 0) { | 1042 | if (ret < 0) { |
965 | printk("%s: could not set ts feed\n", dev->name); | 1043 | printk("%s: could not set ts feed\n", dev->name); |
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c index 3852430d0260..134c2bbbeeb5 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.c +++ b/drivers/media/dvb/dvb-core/dvbdev.c | |||
@@ -236,7 +236,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, | |||
236 | "dvb/adapter%d/%s%d", adap->num, dnames[type], id); | 236 | "dvb/adapter%d/%s%d", adap->num, dnames[type], id); |
237 | 237 | ||
238 | class_device_create(dvb_class, NULL, MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)), | 238 | class_device_create(dvb_class, NULL, MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)), |
239 | NULL, "dvb%d.%s%d", adap->num, dnames[type], id); | 239 | adap->device, "dvb%d.%s%d", adap->num, dnames[type], id); |
240 | 240 | ||
241 | dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n", | 241 | dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n", |
242 | adap->num, dnames[type], id, nums2minor(adap->num, type, id), | 242 | adap->num, dnames[type], id, nums2minor(adap->num, type, id), |
@@ -285,7 +285,7 @@ skip: | |||
285 | } | 285 | } |
286 | 286 | ||
287 | 287 | ||
288 | int dvb_register_adapter(struct dvb_adapter *adap, const char *name, struct module *module) | 288 | int dvb_register_adapter(struct dvb_adapter *adap, const char *name, struct module *module, struct device *device) |
289 | { | 289 | { |
290 | int num; | 290 | int num; |
291 | 291 | ||
@@ -306,6 +306,7 @@ int dvb_register_adapter(struct dvb_adapter *adap, const char *name, struct modu | |||
306 | adap->num = num; | 306 | adap->num = num; |
307 | adap->name = name; | 307 | adap->name = name; |
308 | adap->module = module; | 308 | adap->module = module; |
309 | adap->device = device; | ||
309 | 310 | ||
310 | list_add_tail (&adap->list_head, &dvb_adapter_list); | 311 | list_add_tail (&adap->list_head, &dvb_adapter_list); |
311 | 312 | ||
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h index 74ed5853f0fb..d7a976d040d7 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.h +++ b/drivers/media/dvb/dvb-core/dvbdev.h | |||
@@ -51,6 +51,8 @@ struct dvb_adapter { | |||
51 | u8 proposed_mac [6]; | 51 | u8 proposed_mac [6]; |
52 | void* priv; | 52 | void* priv; |
53 | 53 | ||
54 | struct device *device; | ||
55 | |||
54 | struct module *module; | 56 | struct module *module; |
55 | }; | 57 | }; |
56 | 58 | ||
@@ -76,7 +78,7 @@ struct dvb_device { | |||
76 | }; | 78 | }; |
77 | 79 | ||
78 | 80 | ||
79 | extern int dvb_register_adapter (struct dvb_adapter *adap, const char *name, struct module *module); | 81 | extern int dvb_register_adapter (struct dvb_adapter *adap, const char *name, struct module *module, struct device *device); |
80 | extern int dvb_unregister_adapter (struct dvb_adapter *adap); | 82 | extern int dvb_unregister_adapter (struct dvb_adapter *adap); |
81 | 83 | ||
82 | extern int dvb_register_device (struct dvb_adapter *adap, | 84 | extern int dvb_register_device (struct dvb_adapter *adap, |
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index e388fb1567d6..3bc6722a6443 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig | |||
@@ -88,6 +88,7 @@ config DVB_USB_CXUSB | |||
88 | select DVB_CX22702 | 88 | select DVB_CX22702 |
89 | select DVB_LGDT330X | 89 | select DVB_LGDT330X |
90 | select DVB_MT352 | 90 | select DVB_MT352 |
91 | select DVB_ZL10353 | ||
91 | help | 92 | help |
92 | Say Y here to support the Conexant USB2.0 hybrid reference design. | 93 | Say Y here to support the Conexant USB2.0 hybrid reference design. |
93 | Currently, only DVB and ATSC modes are supported, analog mode | 94 | Currently, only DVB and ATSC modes are supported, analog mode |
@@ -130,6 +131,15 @@ config DVB_USB_VP702X | |||
130 | 131 | ||
131 | DVB-S USB2.0 receivers. | 132 | DVB-S USB2.0 receivers. |
132 | 133 | ||
134 | config DVB_USB_GP8PSK | ||
135 | tristate "GENPIX 8PSK->USB module support" | ||
136 | depends on DVB_USB | ||
137 | help | ||
138 | Say Y here to support the | ||
139 | GENPIX 8psk module | ||
140 | |||
141 | DVB-S USB2.0 receivers. | ||
142 | |||
133 | config DVB_USB_NOVA_T_USB2 | 143 | config DVB_USB_NOVA_T_USB2 |
134 | tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support" | 144 | tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support" |
135 | depends on DVB_USB | 145 | depends on DVB_USB |
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile index 2dc9aad9681e..9643f56c7fe9 100644 --- a/drivers/media/dvb/dvb-usb/Makefile +++ b/drivers/media/dvb/dvb-usb/Makefile | |||
@@ -7,6 +7,9 @@ obj-$(CONFIG_DVB_USB_VP7045) += dvb-usb-vp7045.o | |||
7 | dvb-usb-vp702x-objs = vp702x.o vp702x-fe.o | 7 | dvb-usb-vp702x-objs = vp702x.o vp702x-fe.o |
8 | obj-$(CONFIG_DVB_USB_VP702X) += dvb-usb-vp702x.o | 8 | obj-$(CONFIG_DVB_USB_VP702X) += dvb-usb-vp702x.o |
9 | 9 | ||
10 | dvb-usb-gp8psk-objs = gp8psk.o gp8psk-fe.o | ||
11 | obj-$(CONFIG_DVB_USB_GP8PSK) += dvb-usb-gp8psk.o | ||
12 | |||
10 | dvb-usb-dtt200u-objs = dtt200u.o dtt200u-fe.o | 13 | dvb-usb-dtt200u-objs = dtt200u.o dtt200u-fe.o |
11 | obj-$(CONFIG_DVB_USB_DTT200U) += dvb-usb-dtt200u.o | 14 | obj-$(CONFIG_DVB_USB_DTT200U) += dvb-usb-dtt200u.o |
12 | 15 | ||
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c index 1f0d3e995c8d..ae23bdde42a8 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.c +++ b/drivers/media/dvb/dvb-usb/cxusb.c | |||
@@ -27,8 +27,10 @@ | |||
27 | 27 | ||
28 | #include "cx22702.h" | 28 | #include "cx22702.h" |
29 | #include "lgdt330x.h" | 29 | #include "lgdt330x.h" |
30 | #include "lg_h06xf.h" | ||
30 | #include "mt352.h" | 31 | #include "mt352.h" |
31 | #include "mt352_priv.h" | 32 | #include "mt352_priv.h" |
33 | #include "zl10353.h" | ||
32 | 34 | ||
33 | /* debug */ | 35 | /* debug */ |
34 | int dvb_usb_cxusb_debug; | 36 | int dvb_usb_cxusb_debug; |
@@ -322,32 +324,37 @@ static int cxusb_mt352_demod_init(struct dvb_frontend* fe) | |||
322 | return 0; | 324 | return 0; |
323 | } | 325 | } |
324 | 326 | ||
327 | static int cxusb_lgh064f_tuner_set_params(struct dvb_frontend *fe, | ||
328 | struct dvb_frontend_parameters *fep) | ||
329 | { | ||
330 | struct dvb_usb_device *d = fe->dvb->priv; | ||
331 | return lg_h06xf_pll_set(fe, &d->i2c_adap, fep); | ||
332 | } | ||
333 | |||
325 | static struct cx22702_config cxusb_cx22702_config = { | 334 | static struct cx22702_config cxusb_cx22702_config = { |
326 | .demod_address = 0x63, | 335 | .demod_address = 0x63, |
327 | 336 | ||
328 | .output_mode = CX22702_PARALLEL_OUTPUT, | 337 | .output_mode = CX22702_PARALLEL_OUTPUT, |
329 | |||
330 | .pll_init = dvb_usb_pll_init_i2c, | ||
331 | .pll_set = dvb_usb_pll_set_i2c, | ||
332 | }; | 338 | }; |
333 | 339 | ||
334 | static struct lgdt330x_config cxusb_lgdt3303_config = { | 340 | static struct lgdt330x_config cxusb_lgdt3303_config = { |
335 | .demod_address = 0x0e, | 341 | .demod_address = 0x0e, |
336 | .demod_chip = LGDT3303, | 342 | .demod_chip = LGDT3303, |
337 | .pll_set = dvb_usb_pll_set_i2c, | ||
338 | }; | 343 | }; |
339 | 344 | ||
340 | static struct mt352_config cxusb_dee1601_config = { | 345 | static struct mt352_config cxusb_dee1601_config = { |
341 | .demod_address = 0x0f, | 346 | .demod_address = 0x0f, |
342 | .demod_init = cxusb_dee1601_demod_init, | 347 | .demod_init = cxusb_dee1601_demod_init, |
343 | .pll_set = dvb_usb_pll_set, | ||
344 | }; | 348 | }; |
345 | 349 | ||
346 | struct mt352_config cxusb_mt352_config = { | 350 | static struct zl10353_config cxusb_zl10353_dee1601_config = { |
351 | .demod_address = 0x0f, | ||
352 | }; | ||
353 | |||
354 | static struct mt352_config cxusb_mt352_config = { | ||
347 | /* used in both lgz201 and th7579 */ | 355 | /* used in both lgz201 and th7579 */ |
348 | .demod_address = 0x0f, | 356 | .demod_address = 0x0f, |
349 | .demod_init = cxusb_mt352_demod_init, | 357 | .demod_init = cxusb_mt352_demod_init, |
350 | .pll_set = dvb_usb_pll_set, | ||
351 | }; | 358 | }; |
352 | 359 | ||
353 | /* Callbacks for DVB USB */ | 360 | /* Callbacks for DVB USB */ |
@@ -357,17 +364,10 @@ static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_device *d) | |||
357 | d->pll_addr = 0x61; | 364 | d->pll_addr = 0x61; |
358 | memcpy(d->pll_init, bpll, 4); | 365 | memcpy(d->pll_init, bpll, 4); |
359 | d->pll_desc = &dvb_pll_fmd1216me; | 366 | d->pll_desc = &dvb_pll_fmd1216me; |
360 | return 0; | ||
361 | } | ||
362 | 367 | ||
363 | static int cxusb_lgh064f_tuner_attach(struct dvb_usb_device *d) | 368 | d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c; |
364 | { | 369 | d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c; |
365 | u8 bpll[4] = { 0x00, 0x00, 0x18, 0x50 }; | 370 | |
366 | /* bpll[2] : unset bit 3, set bits 4&5 | ||
367 | bpll[3] : 0x50 - digital, 0x20 - analog */ | ||
368 | d->pll_addr = 0x61; | ||
369 | memcpy(d->pll_init, bpll, 4); | ||
370 | d->pll_desc = &dvb_pll_tdvs_tua6034; | ||
371 | return 0; | 371 | return 0; |
372 | } | 372 | } |
373 | 373 | ||
@@ -375,6 +375,7 @@ static int cxusb_dee1601_tuner_attach(struct dvb_usb_device *d) | |||
375 | { | 375 | { |
376 | d->pll_addr = 0x61; | 376 | d->pll_addr = 0x61; |
377 | d->pll_desc = &dvb_pll_thomson_dtt7579; | 377 | d->pll_desc = &dvb_pll_thomson_dtt7579; |
378 | d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs; | ||
378 | return 0; | 379 | return 0; |
379 | } | 380 | } |
380 | 381 | ||
@@ -382,6 +383,7 @@ static int cxusb_lgz201_tuner_attach(struct dvb_usb_device *d) | |||
382 | { | 383 | { |
383 | d->pll_addr = 0x61; | 384 | d->pll_addr = 0x61; |
384 | d->pll_desc = &dvb_pll_lg_z201; | 385 | d->pll_desc = &dvb_pll_lg_z201; |
386 | d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs; | ||
385 | return 0; | 387 | return 0; |
386 | } | 388 | } |
387 | 389 | ||
@@ -389,6 +391,13 @@ static int cxusb_dtt7579_tuner_attach(struct dvb_usb_device *d) | |||
389 | { | 391 | { |
390 | d->pll_addr = 0x60; | 392 | d->pll_addr = 0x60; |
391 | d->pll_desc = &dvb_pll_thomson_dtt7579; | 393 | d->pll_desc = &dvb_pll_thomson_dtt7579; |
394 | d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs; | ||
395 | return 0; | ||
396 | } | ||
397 | |||
398 | static int cxusb_lgdt3303_tuner_attach(struct dvb_usb_device *d) | ||
399 | { | ||
400 | d->fe->ops.tuner_ops.set_params = cxusb_lgh064f_tuner_set_params; | ||
392 | return 0; | 401 | return 0; |
393 | } | 402 | } |
394 | 403 | ||
@@ -439,7 +448,8 @@ static int cxusb_dee1601_frontend_attach(struct dvb_usb_device *d) | |||
439 | 448 | ||
440 | cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0); | 449 | cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0); |
441 | 450 | ||
442 | if ((d->fe = mt352_attach(&cxusb_dee1601_config, &d->i2c_adap)) != NULL) | 451 | if (((d->fe = mt352_attach(&cxusb_dee1601_config, &d->i2c_adap)) != NULL) || |
452 | ((d->fe = zl10353_attach(&cxusb_zl10353_dee1601_config, &d->i2c_adap)) != NULL)) | ||
443 | return 0; | 453 | return 0; |
444 | 454 | ||
445 | return -EIO; | 455 | return -EIO; |
@@ -555,7 +565,7 @@ static struct dvb_usb_properties cxusb_bluebird_lgh064f_properties = { | |||
555 | .streaming_ctrl = cxusb_streaming_ctrl, | 565 | .streaming_ctrl = cxusb_streaming_ctrl, |
556 | .power_ctrl = cxusb_bluebird_power_ctrl, | 566 | .power_ctrl = cxusb_bluebird_power_ctrl, |
557 | .frontend_attach = cxusb_lgdt3303_frontend_attach, | 567 | .frontend_attach = cxusb_lgdt3303_frontend_attach, |
558 | .tuner_attach = cxusb_lgh064f_tuner_attach, | 568 | .tuner_attach = cxusb_lgdt3303_tuner_attach, |
559 | 569 | ||
560 | .i2c_algo = &cxusb_i2c_algo, | 570 | .i2c_algo = &cxusb_i2c_algo, |
561 | 571 | ||
diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c index 2d52b76671d3..abd75b4a350d 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-common.c +++ b/drivers/media/dvb/dvb-usb/dibusb-common.c | |||
@@ -173,11 +173,10 @@ int dibusb_dib3000mc_frontend_attach(struct dvb_usb_device *d) | |||
173 | struct dib3000_config demod_cfg; | 173 | struct dib3000_config demod_cfg; |
174 | struct dibusb_state *st = d->priv; | 174 | struct dibusb_state *st = d->priv; |
175 | 175 | ||
176 | demod_cfg.pll_set = dvb_usb_pll_set_i2c; | ||
177 | demod_cfg.pll_init = dvb_usb_pll_init_i2c; | ||
178 | |||
179 | for (demod_cfg.demod_address = 0x8; demod_cfg.demod_address < 0xd; demod_cfg.demod_address++) | 176 | for (demod_cfg.demod_address = 0x8; demod_cfg.demod_address < 0xd; demod_cfg.demod_address++) |
180 | if ((d->fe = dib3000mc_attach(&demod_cfg,&d->i2c_adap,&st->ops)) != NULL) { | 177 | if ((d->fe = dib3000mc_attach(&demod_cfg,&d->i2c_adap,&st->ops)) != NULL) { |
178 | d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c; | ||
179 | d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c; | ||
181 | d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl; | 180 | d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl; |
182 | return 0; | 181 | return 0; |
183 | } | 182 | } |
@@ -190,6 +189,10 @@ int dibusb_dib3000mc_tuner_attach (struct dvb_usb_device *d) | |||
190 | { | 189 | { |
191 | d->pll_addr = 0x60; | 190 | d->pll_addr = 0x60; |
192 | d->pll_desc = &dvb_pll_env57h1xd5; | 191 | d->pll_desc = &dvb_pll_env57h1xd5; |
192 | |||
193 | d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c; | ||
194 | d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c; | ||
195 | |||
193 | return 0; | 196 | return 0; |
194 | } | 197 | } |
195 | EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach); | 198 | EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach); |
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c index dd5a13195886..f4c45f386ebc 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-mb.c +++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c | |||
@@ -20,11 +20,12 @@ static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_device *d) | |||
20 | struct dibusb_state *st = d->priv; | 20 | struct dibusb_state *st = d->priv; |
21 | 21 | ||
22 | demod_cfg.demod_address = 0x8; | 22 | demod_cfg.demod_address = 0x8; |
23 | demod_cfg.pll_set = dvb_usb_pll_set_i2c; | ||
24 | demod_cfg.pll_init = dvb_usb_pll_init_i2c; | ||
25 | 23 | ||
26 | if ((d->fe = dib3000mb_attach(&demod_cfg,&d->i2c_adap,&st->ops)) == NULL) | 24 | if ((d->fe = dib3000mb_attach(&demod_cfg,&d->i2c_adap,&st->ops)) == NULL) { |
25 | d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c; | ||
26 | d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c; | ||
27 | return -ENODEV; | 27 | return -ENODEV; |
28 | } | ||
28 | 29 | ||
29 | d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl; | 30 | d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl; |
30 | 31 | ||
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c index 91136c00ce9d..c14d9efb48fd 100644 --- a/drivers/media/dvb/dvb-usb/digitv.c +++ b/drivers/media/dvb/dvb-usb/digitv.c | |||
@@ -112,27 +112,30 @@ static int digitv_mt352_demod_init(struct dvb_frontend *fe) | |||
112 | 112 | ||
113 | static struct mt352_config digitv_mt352_config = { | 113 | static struct mt352_config digitv_mt352_config = { |
114 | .demod_init = digitv_mt352_demod_init, | 114 | .demod_init = digitv_mt352_demod_init, |
115 | .pll_set = dvb_usb_pll_set, | ||
116 | }; | 115 | }; |
117 | 116 | ||
118 | static int digitv_nxt6000_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) | 117 | static int digitv_nxt6000_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) |
119 | { | 118 | { |
120 | struct dvb_usb_device *d = fe->dvb->priv; | 119 | struct dvb_usb_device *d = fe->dvb->priv; |
121 | u8 b[5]; | 120 | u8 b[5]; |
122 | dvb_usb_pll_set(fe,fep,b); | 121 | dvb_usb_tuner_calc_regs(fe,fep,b, 5); |
123 | return digitv_ctrl_msg(d,USB_WRITE_TUNER,0,&b[1],4,NULL,0); | 122 | return digitv_ctrl_msg(d,USB_WRITE_TUNER,0,&b[1],4,NULL,0); |
124 | } | 123 | } |
125 | 124 | ||
126 | static struct nxt6000_config digitv_nxt6000_config = { | 125 | static struct nxt6000_config digitv_nxt6000_config = { |
127 | .clock_inversion = 1, | 126 | .clock_inversion = 1, |
128 | .pll_set = digitv_nxt6000_pll_set, | ||
129 | }; | 127 | }; |
130 | 128 | ||
131 | static int digitv_frontend_attach(struct dvb_usb_device *d) | 129 | static int digitv_frontend_attach(struct dvb_usb_device *d) |
132 | { | 130 | { |
133 | if ((d->fe = mt352_attach(&digitv_mt352_config, &d->i2c_adap)) != NULL || | 131 | if ((d->fe = mt352_attach(&digitv_mt352_config, &d->i2c_adap)) != NULL) { |
134 | (d->fe = nxt6000_attach(&digitv_nxt6000_config, &d->i2c_adap)) != NULL) | 132 | d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs; |
135 | return 0; | 133 | return 0; |
134 | } | ||
135 | if ((d->fe = nxt6000_attach(&digitv_nxt6000_config, &d->i2c_adap)) != NULL) { | ||
136 | d->fe->ops.tuner_ops.set_params = digitv_nxt6000_tuner_set_params; | ||
137 | return 0; | ||
138 | } | ||
136 | return -EIO; | 139 | return -EIO; |
137 | } | 140 | } |
138 | 141 | ||
diff --git a/drivers/media/dvb/dvb-usb/dtt200u-fe.c b/drivers/media/dvb/dvb-usb/dtt200u-fe.c index cd21ddbfd054..17413adec7a1 100644 --- a/drivers/media/dvb/dvb-usb/dtt200u-fe.c +++ b/drivers/media/dvb/dvb-usb/dtt200u-fe.c | |||
@@ -18,7 +18,6 @@ struct dtt200u_fe_state { | |||
18 | 18 | ||
19 | struct dvb_frontend_parameters fep; | 19 | struct dvb_frontend_parameters fep; |
20 | struct dvb_frontend frontend; | 20 | struct dvb_frontend frontend; |
21 | struct dvb_frontend_ops ops; | ||
22 | }; | 21 | }; |
23 | 22 | ||
24 | static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat) | 23 | static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat) |
@@ -163,16 +162,13 @@ struct dvb_frontend* dtt200u_fe_attach(struct dvb_usb_device *d) | |||
163 | deb_info("attaching frontend dtt200u\n"); | 162 | deb_info("attaching frontend dtt200u\n"); |
164 | 163 | ||
165 | state->d = d; | 164 | state->d = d; |
166 | memcpy(&state->ops,&dtt200u_fe_ops,sizeof(struct dvb_frontend_ops)); | ||
167 | 165 | ||
168 | state->frontend.ops = &state->ops; | 166 | memcpy(&state->frontend.ops,&dtt200u_fe_ops,sizeof(struct dvb_frontend_ops)); |
169 | state->frontend.demodulator_priv = state; | 167 | state->frontend.demodulator_priv = state; |
170 | 168 | ||
171 | goto success; | 169 | return &state->frontend; |
172 | error: | 170 | error: |
173 | return NULL; | 171 | return NULL; |
174 | success: | ||
175 | return &state->frontend; | ||
176 | } | 172 | } |
177 | 173 | ||
178 | static struct dvb_frontend_ops dtt200u_fe_ops = { | 174 | static struct dvb_frontend_ops dtt200u_fe_ops = { |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c index 6fa92100248b..ec631708c394 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c | |||
@@ -82,7 +82,7 @@ int dvb_usb_dvb_init(struct dvb_usb_device *d) | |||
82 | int ret; | 82 | int ret; |
83 | 83 | ||
84 | if ((ret = dvb_register_adapter(&d->dvb_adap, d->desc->name, | 84 | if ((ret = dvb_register_adapter(&d->dvb_adap, d->desc->name, |
85 | d->owner)) < 0) { | 85 | d->owner, &d->udev->dev)) < 0) { |
86 | deb_info("dvb_register_adapter failed: error %d", ret); | 86 | deb_info("dvb_register_adapter failed: error %d", ret); |
87 | goto err; | 87 | goto err; |
88 | } | 88 | } |
@@ -121,16 +121,15 @@ int dvb_usb_dvb_init(struct dvb_usb_device *d) | |||
121 | 121 | ||
122 | dvb_net_init(&d->dvb_adap, &d->dvb_net, &d->demux.dmx); | 122 | dvb_net_init(&d->dvb_adap, &d->dvb_net, &d->demux.dmx); |
123 | 123 | ||
124 | goto success; | 124 | d->state |= DVB_USB_STATE_DVB; |
125 | return 0; | ||
126 | |||
125 | err_dmx_dev: | 127 | err_dmx_dev: |
126 | dvb_dmx_release(&d->demux); | 128 | dvb_dmx_release(&d->demux); |
127 | err_dmx: | 129 | err_dmx: |
128 | dvb_unregister_adapter(&d->dvb_adap); | 130 | dvb_unregister_adapter(&d->dvb_adap); |
129 | err: | 131 | err: |
130 | return ret; | 132 | return ret; |
131 | success: | ||
132 | d->state |= DVB_USB_STATE_DVB; | ||
133 | return 0; | ||
134 | } | 133 | } |
135 | 134 | ||
136 | int dvb_usb_dvb_exit(struct dvb_usb_device *d) | 135 | int dvb_usb_dvb_exit(struct dvb_usb_device *d) |
@@ -184,13 +183,13 @@ int dvb_usb_fe_init(struct dvb_usb_device* d) | |||
184 | 183 | ||
185 | /* re-assign sleep and wakeup functions */ | 184 | /* re-assign sleep and wakeup functions */ |
186 | if (d->fe != NULL) { | 185 | if (d->fe != NULL) { |
187 | d->fe_init = d->fe->ops->init; d->fe->ops->init = dvb_usb_fe_wakeup; | 186 | d->fe_init = d->fe->ops.init; d->fe->ops.init = dvb_usb_fe_wakeup; |
188 | d->fe_sleep = d->fe->ops->sleep; d->fe->ops->sleep = dvb_usb_fe_sleep; | 187 | d->fe_sleep = d->fe->ops.sleep; d->fe->ops.sleep = dvb_usb_fe_sleep; |
189 | 188 | ||
190 | if (dvb_register_frontend(&d->dvb_adap, d->fe)) { | 189 | if (dvb_register_frontend(&d->dvb_adap, d->fe)) { |
191 | err("Frontend registration failed."); | 190 | err("Frontend registration failed."); |
192 | if (d->fe->ops->release) | 191 | if (d->fe->ops.release) |
193 | d->fe->ops->release(d->fe); | 192 | d->fe->ops.release(d->fe); |
194 | d->fe = NULL; | 193 | d->fe = NULL; |
195 | return -ENODEV; | 194 | return -ENODEV; |
196 | } | 195 | } |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c index 9b254532af4d..6b611a725093 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c | |||
@@ -46,7 +46,7 @@ int dvb_usb_i2c_exit(struct dvb_usb_device *d) | |||
46 | return 0; | 46 | return 0; |
47 | } | 47 | } |
48 | 48 | ||
49 | int dvb_usb_pll_init_i2c(struct dvb_frontend *fe) | 49 | int dvb_usb_tuner_init_i2c(struct dvb_frontend *fe) |
50 | { | 50 | { |
51 | struct dvb_usb_device *d = fe->dvb->priv; | 51 | struct dvb_usb_device *d = fe->dvb->priv; |
52 | struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = d->pll_init, .len = 4 }; | 52 | struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = d->pll_init, .len = 4 }; |
@@ -63,6 +63,8 @@ int dvb_usb_pll_init_i2c(struct dvb_frontend *fe) | |||
63 | deb_pll("pll-buf: %x %x %x %x\n",d->pll_init[0],d->pll_init[1], | 63 | deb_pll("pll-buf: %x %x %x %x\n",d->pll_init[0],d->pll_init[1], |
64 | d->pll_init[2],d->pll_init[3]); | 64 | d->pll_init[2],d->pll_init[3]); |
65 | 65 | ||
66 | if (fe->ops.i2c_gate_ctrl) | ||
67 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
66 | if (i2c_transfer (&d->i2c_adap, &msg, 1) != 1) { | 68 | if (i2c_transfer (&d->i2c_adap, &msg, 1) != 1) { |
67 | err("tuner i2c write failed for pll_init."); | 69 | err("tuner i2c write failed for pll_init."); |
68 | ret = -EREMOTEIO; | 70 | ret = -EREMOTEIO; |
@@ -73,38 +75,42 @@ int dvb_usb_pll_init_i2c(struct dvb_frontend *fe) | |||
73 | d->tuner_pass_ctrl(fe,0,d->pll_addr); | 75 | d->tuner_pass_ctrl(fe,0,d->pll_addr); |
74 | return ret; | 76 | return ret; |
75 | } | 77 | } |
76 | EXPORT_SYMBOL(dvb_usb_pll_init_i2c); | 78 | EXPORT_SYMBOL(dvb_usb_tuner_init_i2c); |
77 | 79 | ||
78 | int dvb_usb_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep, u8 b[5]) | 80 | int dvb_usb_tuner_calc_regs(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep, u8 *b, int buf_len) |
79 | { | 81 | { |
80 | struct dvb_usb_device *d = fe->dvb->priv; | 82 | struct dvb_usb_device *d = fe->dvb->priv; |
81 | 83 | ||
84 | if (buf_len != 5) | ||
85 | return -EINVAL; | ||
82 | if (d->pll_desc == NULL) | 86 | if (d->pll_desc == NULL) |
83 | return 0; | 87 | return 0; |
84 | 88 | ||
85 | deb_pll("pll addr: %x, freq: %d %p\n",d->pll_addr,fep->frequency,d->pll_desc); | 89 | deb_pll("pll addr: %x, freq: %d %p\n",d->pll_addr,fep->frequency,d->pll_desc); |
86 | 90 | ||
87 | b[0] = d->pll_addr << 1; | 91 | b[0] = d->pll_addr; |
88 | dvb_pll_configure(d->pll_desc,&b[1],fep->frequency,fep->u.ofdm.bandwidth); | 92 | dvb_pll_configure(d->pll_desc,&b[1],fep->frequency,fep->u.ofdm.bandwidth); |
89 | 93 | ||
90 | deb_pll("pll-buf: %x %x %x %x %x\n",b[0],b[1],b[2],b[3],b[4]); | 94 | deb_pll("pll-buf: %x %x %x %x %x\n",b[0],b[1],b[2],b[3],b[4]); |
91 | 95 | ||
92 | return 0; | 96 | return 5; |
93 | } | 97 | } |
94 | EXPORT_SYMBOL(dvb_usb_pll_set); | 98 | EXPORT_SYMBOL(dvb_usb_tuner_calc_regs); |
95 | 99 | ||
96 | int dvb_usb_pll_set_i2c(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) | 100 | int dvb_usb_tuner_set_params_i2c(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) |
97 | { | 101 | { |
98 | struct dvb_usb_device *d = fe->dvb->priv; | 102 | struct dvb_usb_device *d = fe->dvb->priv; |
99 | int ret = 0; | 103 | int ret = 0; |
100 | u8 b[5]; | 104 | u8 b[5]; |
101 | struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = &b[1], .len = 4 }; | 105 | struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = &b[1], .len = 4 }; |
102 | 106 | ||
103 | dvb_usb_pll_set(fe,fep,b); | 107 | dvb_usb_tuner_calc_regs(fe,fep,b,5); |
104 | 108 | ||
105 | if (d->tuner_pass_ctrl) | 109 | if (d->tuner_pass_ctrl) |
106 | d->tuner_pass_ctrl(fe,1,d->pll_addr); | 110 | d->tuner_pass_ctrl(fe,1,d->pll_addr); |
107 | 111 | ||
112 | if (fe->ops.i2c_gate_ctrl) | ||
113 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
108 | if (i2c_transfer (&d->i2c_adap, &msg, 1) != 1) { | 114 | if (i2c_transfer (&d->i2c_adap, &msg, 1) != 1) { |
109 | err("tuner i2c write failed for pll_set."); | 115 | err("tuner i2c write failed for pll_set."); |
110 | ret = -EREMOTEIO; | 116 | ret = -EREMOTEIO; |
@@ -116,4 +122,4 @@ int dvb_usb_pll_set_i2c(struct dvb_frontend *fe, struct dvb_frontend_parameters | |||
116 | 122 | ||
117 | return ret; | 123 | return ret; |
118 | } | 124 | } |
119 | EXPORT_SYMBOL(dvb_usb_pll_set_i2c); | 125 | EXPORT_SYMBOL(dvb_usb_tuner_set_params_i2c); |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index cb239049b098..95698918bc11 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | |||
@@ -31,6 +31,7 @@ | |||
31 | #define USB_VID_VISIONPLUS 0x13d3 | 31 | #define USB_VID_VISIONPLUS 0x13d3 |
32 | #define USB_VID_TWINHAN 0x1822 | 32 | #define USB_VID_TWINHAN 0x1822 |
33 | #define USB_VID_ULTIMA_ELECTRONIC 0x05d8 | 33 | #define USB_VID_ULTIMA_ELECTRONIC 0x05d8 |
34 | #define USB_VID_GENPIX 0x09c0 | ||
34 | 35 | ||
35 | /* Product IDs */ | 36 | /* Product IDs */ |
36 | #define USB_PID_ADSTECH_USB2_COLD 0xa333 | 37 | #define USB_PID_ADSTECH_USB2_COLD 0xa333 |
@@ -104,5 +105,6 @@ | |||
104 | #define USB_PID_KYE_DVB_T_WARM 0x701f | 105 | #define USB_PID_KYE_DVB_T_WARM 0x701f |
105 | #define USB_PID_PCTV_200E 0x020e | 106 | #define USB_PID_PCTV_200E 0x020e |
106 | #define USB_PID_PCTV_400E 0x020f | 107 | #define USB_PID_PCTV_400E 0x020f |
107 | 108 | #define USB_PID_GENPIX_8PSK_COLD 0x0200 | |
109 | #define USB_PID_GENPIX_8PSK_WARM 0x0201 | ||
108 | #endif | 110 | #endif |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h index fead958a57e3..4cf9f89c51bf 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb.h | |||
@@ -330,9 +330,9 @@ extern int dvb_usb_generic_write(struct dvb_usb_device *, u8 *, u16); | |||
330 | extern int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *, u8[], u32 *, int *); | 330 | extern int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *, u8[], u32 *, int *); |
331 | 331 | ||
332 | /* commonly used pll init and set functions */ | 332 | /* commonly used pll init and set functions */ |
333 | extern int dvb_usb_pll_init_i2c(struct dvb_frontend *); | 333 | extern int dvb_usb_tuner_init_i2c(struct dvb_frontend *); |
334 | extern int dvb_usb_pll_set(struct dvb_frontend *, struct dvb_frontend_parameters *, u8[]); | 334 | extern int dvb_usb_tuner_calc_regs(struct dvb_frontend *, struct dvb_frontend_parameters *, u8 *buf, int buf_len); |
335 | extern int dvb_usb_pll_set_i2c(struct dvb_frontend *, struct dvb_frontend_parameters *); | 335 | extern int dvb_usb_tuner_set_params_i2c(struct dvb_frontend *, struct dvb_frontend_parameters *); |
336 | 336 | ||
337 | /* commonly used firmware download types and function */ | 337 | /* commonly used firmware download types and function */ |
338 | struct hexline { | 338 | struct hexline { |
diff --git a/drivers/media/dvb/dvb-usb/gp8psk-fe.c b/drivers/media/dvb/dvb-usb/gp8psk-fe.c new file mode 100644 index 000000000000..6ccbdc9cd772 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/gp8psk-fe.c | |||
@@ -0,0 +1,272 @@ | |||
1 | /* DVB USB compliant Linux driver for the | ||
2 | * - GENPIX 8pks/qpsk USB2.0 DVB-S module | ||
3 | * | ||
4 | * Copyright (C) 2006 Alan Nisota (alannisota@gmail.com) | ||
5 | * | ||
6 | * Thanks to GENPIX for the sample code used to implement this module. | ||
7 | * | ||
8 | * This module is based off the vp7045 and vp702x modules | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the Free | ||
12 | * Software Foundation, version 2. | ||
13 | * | ||
14 | * see Documentation/dvb/README.dvb-usb for more information | ||
15 | */ | ||
16 | #include "gp8psk.h" | ||
17 | |||
18 | struct gp8psk_fe_state { | ||
19 | struct dvb_frontend fe; | ||
20 | |||
21 | struct dvb_usb_device *d; | ||
22 | |||
23 | u16 snr; | ||
24 | |||
25 | unsigned long next_snr_check; | ||
26 | }; | ||
27 | |||
28 | static int gp8psk_fe_read_status(struct dvb_frontend* fe, fe_status_t *status) | ||
29 | { | ||
30 | struct gp8psk_fe_state *st = fe->demodulator_priv; | ||
31 | u8 lock; | ||
32 | |||
33 | if (gp8psk_usb_in_op(st->d, GET_SIGNAL_LOCK, 0, 0, &lock,1)) | ||
34 | return -EINVAL; | ||
35 | |||
36 | if (lock) | ||
37 | *status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_SIGNAL | FE_HAS_CARRIER; | ||
38 | else | ||
39 | *status = 0; | ||
40 | |||
41 | return 0; | ||
42 | } | ||
43 | |||
44 | /* not supported by this Frontend */ | ||
45 | static int gp8psk_fe_read_ber(struct dvb_frontend* fe, u32 *ber) | ||
46 | { | ||
47 | (void) fe; | ||
48 | *ber = 0; | ||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | /* not supported by this Frontend */ | ||
53 | static int gp8psk_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc) | ||
54 | { | ||
55 | (void) fe; | ||
56 | *unc = 0; | ||
57 | return 0; | ||
58 | } | ||
59 | |||
60 | static int gp8psk_fe_read_snr(struct dvb_frontend* fe, u16 *snr) | ||
61 | { | ||
62 | struct gp8psk_fe_state *st = fe->demodulator_priv; | ||
63 | u8 buf[2]; | ||
64 | |||
65 | if (time_after(jiffies,st->next_snr_check)) { | ||
66 | gp8psk_usb_in_op(st->d,GET_SIGNAL_STRENGTH,0,0,buf,2); | ||
67 | *snr = (int)(buf[1]) << 8 | buf[0]; | ||
68 | /* snr is reported in dBu*256 */ | ||
69 | /* snr / 38.4 ~= 100% strength */ | ||
70 | /* snr * 17 returns 100% strength as 65535 */ | ||
71 | if (*snr <= 3855) | ||
72 | *snr = (*snr<<4) + *snr; // snr * 17 | ||
73 | else | ||
74 | *snr = 65535; | ||
75 | st->next_snr_check = jiffies + (10*HZ)/1000; | ||
76 | } else { | ||
77 | *snr = st->snr; | ||
78 | } | ||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | static int gp8psk_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength) | ||
83 | { | ||
84 | return gp8psk_fe_read_snr(fe, strength); | ||
85 | } | ||
86 | |||
87 | static int gp8psk_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) | ||
88 | { | ||
89 | tune->min_delay_ms = 800; | ||
90 | return 0; | ||
91 | } | ||
92 | |||
93 | static int gp8psk_fe_set_frontend(struct dvb_frontend* fe, | ||
94 | struct dvb_frontend_parameters *fep) | ||
95 | { | ||
96 | struct gp8psk_fe_state *state = fe->demodulator_priv; | ||
97 | u8 cmd[10]; | ||
98 | u32 freq = fep->frequency * 1000; | ||
99 | |||
100 | cmd[4] = freq & 0xff; | ||
101 | cmd[5] = (freq >> 8) & 0xff; | ||
102 | cmd[6] = (freq >> 16) & 0xff; | ||
103 | cmd[7] = (freq >> 24) & 0xff; | ||
104 | |||
105 | switch(fe->ops.info.type) { | ||
106 | case FE_QPSK: | ||
107 | cmd[0] = fep->u.qpsk.symbol_rate & 0xff; | ||
108 | cmd[1] = (fep->u.qpsk.symbol_rate >> 8) & 0xff; | ||
109 | cmd[2] = (fep->u.qpsk.symbol_rate >> 16) & 0xff; | ||
110 | cmd[3] = (fep->u.qpsk.symbol_rate >> 24) & 0xff; | ||
111 | cmd[8] = ADV_MOD_DVB_QPSK; | ||
112 | cmd[9] = 0x03; /*ADV_MOD_FEC_XXX*/ | ||
113 | break; | ||
114 | default: | ||
115 | // other modes are unsuported right now | ||
116 | cmd[0] = 0; | ||
117 | cmd[1] = 0; | ||
118 | cmd[2] = 0; | ||
119 | cmd[3] = 0; | ||
120 | cmd[8] = 0; | ||
121 | cmd[9] = 0; | ||
122 | break; | ||
123 | } | ||
124 | |||
125 | gp8psk_usb_out_op(state->d,TUNE_8PSK,0,0,cmd,10); | ||
126 | |||
127 | state->next_snr_check = jiffies; | ||
128 | |||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | static int gp8psk_fe_get_frontend(struct dvb_frontend* fe, | ||
133 | struct dvb_frontend_parameters *fep) | ||
134 | { | ||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | |||
139 | static int gp8psk_fe_send_diseqc_msg (struct dvb_frontend* fe, | ||
140 | struct dvb_diseqc_master_cmd *m) | ||
141 | { | ||
142 | struct gp8psk_fe_state *st = fe->demodulator_priv; | ||
143 | |||
144 | deb_fe("%s\n",__FUNCTION__); | ||
145 | |||
146 | if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, m->msg[0], 0, | ||
147 | m->msg, m->msg_len)) { | ||
148 | return -EINVAL; | ||
149 | } | ||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | static int gp8psk_fe_send_diseqc_burst (struct dvb_frontend* fe, | ||
154 | fe_sec_mini_cmd_t burst) | ||
155 | { | ||
156 | struct gp8psk_fe_state *st = fe->demodulator_priv; | ||
157 | u8 cmd; | ||
158 | |||
159 | deb_fe("%s\n",__FUNCTION__); | ||
160 | |||
161 | /* These commands are certainly wrong */ | ||
162 | cmd = (burst == SEC_MINI_A) ? 0x00 : 0x01; | ||
163 | |||
164 | if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, cmd, 0, | ||
165 | &cmd, 0)) { | ||
166 | return -EINVAL; | ||
167 | } | ||
168 | return 0; | ||
169 | } | ||
170 | |||
171 | static int gp8psk_fe_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | ||
172 | { | ||
173 | struct gp8psk_fe_state* state = fe->demodulator_priv; | ||
174 | |||
175 | if (gp8psk_usb_out_op(state->d,SET_22KHZ_TONE, | ||
176 | (tone == SEC_TONE_ON), 0, NULL, 0)) { | ||
177 | return -EINVAL; | ||
178 | } | ||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | static int gp8psk_fe_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage) | ||
183 | { | ||
184 | struct gp8psk_fe_state* state = fe->demodulator_priv; | ||
185 | |||
186 | if (gp8psk_usb_out_op(state->d,SET_LNB_VOLTAGE, | ||
187 | voltage == SEC_VOLTAGE_18, 0, NULL, 0)) { | ||
188 | return -EINVAL; | ||
189 | } | ||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | static int gp8psk_fe_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long sw_cmd) | ||
194 | { | ||
195 | struct gp8psk_fe_state* state = fe->demodulator_priv; | ||
196 | u8 cmd = sw_cmd & 0x7f; | ||
197 | |||
198 | if (gp8psk_usb_out_op(state->d,SET_DN_SWITCH, cmd, 0, | ||
199 | NULL, 0)) { | ||
200 | return -EINVAL; | ||
201 | } | ||
202 | if (gp8psk_usb_out_op(state->d,SET_LNB_VOLTAGE, !!(sw_cmd & 0x80), | ||
203 | 0, NULL, 0)) { | ||
204 | return -EINVAL; | ||
205 | } | ||
206 | |||
207 | return 0; | ||
208 | } | ||
209 | |||
210 | static void gp8psk_fe_release(struct dvb_frontend* fe) | ||
211 | { | ||
212 | struct gp8psk_fe_state *state = fe->demodulator_priv; | ||
213 | kfree(state); | ||
214 | } | ||
215 | |||
216 | static struct dvb_frontend_ops gp8psk_fe_ops; | ||
217 | |||
218 | struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d) | ||
219 | { | ||
220 | struct gp8psk_fe_state *s = kzalloc(sizeof(struct gp8psk_fe_state), GFP_KERNEL); | ||
221 | if (s == NULL) | ||
222 | goto error; | ||
223 | |||
224 | s->d = d; | ||
225 | memcpy(&s->fe.ops, &gp8psk_fe_ops, sizeof(struct dvb_frontend_ops)); | ||
226 | s->fe.demodulator_priv = s; | ||
227 | |||
228 | goto success; | ||
229 | error: | ||
230 | return NULL; | ||
231 | success: | ||
232 | return &s->fe; | ||
233 | } | ||
234 | |||
235 | |||
236 | static struct dvb_frontend_ops gp8psk_fe_ops = { | ||
237 | .info = { | ||
238 | .name = "Genpix 8psk-USB DVB-S", | ||
239 | .type = FE_QPSK, | ||
240 | .frequency_min = 950000, | ||
241 | .frequency_max = 2150000, | ||
242 | .frequency_stepsize = 100, | ||
243 | .symbol_rate_min = 1000000, | ||
244 | .symbol_rate_max = 45000000, | ||
245 | .symbol_rate_tolerance = 500, /* ppm */ | ||
246 | .caps = FE_CAN_INVERSION_AUTO | | ||
247 | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | | ||
248 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | | ||
249 | FE_CAN_QPSK | ||
250 | }, | ||
251 | |||
252 | .release = gp8psk_fe_release, | ||
253 | |||
254 | .init = NULL, | ||
255 | .sleep = NULL, | ||
256 | |||
257 | .set_frontend = gp8psk_fe_set_frontend, | ||
258 | .get_frontend = gp8psk_fe_get_frontend, | ||
259 | .get_tune_settings = gp8psk_fe_get_tune_settings, | ||
260 | |||
261 | .read_status = gp8psk_fe_read_status, | ||
262 | .read_ber = gp8psk_fe_read_ber, | ||
263 | .read_signal_strength = gp8psk_fe_read_signal_strength, | ||
264 | .read_snr = gp8psk_fe_read_snr, | ||
265 | .read_ucblocks = gp8psk_fe_read_unc_blocks, | ||
266 | |||
267 | .diseqc_send_master_cmd = gp8psk_fe_send_diseqc_msg, | ||
268 | .diseqc_send_burst = gp8psk_fe_send_diseqc_burst, | ||
269 | .set_tone = gp8psk_fe_set_tone, | ||
270 | .set_voltage = gp8psk_fe_set_voltage, | ||
271 | .dishnetwork_send_legacy_command = gp8psk_fe_send_legacy_dish_cmd, | ||
272 | }; | ||
diff --git a/drivers/media/dvb/dvb-usb/gp8psk.c b/drivers/media/dvb/dvb-usb/gp8psk.c new file mode 100644 index 000000000000..9a98f3fdae31 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/gp8psk.c | |||
@@ -0,0 +1,256 @@ | |||
1 | /* DVB USB compliant Linux driver for the | ||
2 | * - GENPIX 8pks/qpsk USB2.0 DVB-S module | ||
3 | * | ||
4 | * Copyright (C) 2006 Alan Nisota (alannisota@gmail.com) | ||
5 | * | ||
6 | * Thanks to GENPIX for the sample code used to implement this module. | ||
7 | * | ||
8 | * This module is based off the vp7045 and vp702x modules | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the Free | ||
12 | * Software Foundation, version 2. | ||
13 | * | ||
14 | * see Documentation/dvb/README.dvb-usb for more information | ||
15 | */ | ||
16 | #include "gp8psk.h" | ||
17 | |||
18 | /* debug */ | ||
19 | static char bcm4500_firmware[] = "dvb-usb-gp8psk-02.fw"; | ||
20 | int dvb_usb_gp8psk_debug; | ||
21 | module_param_named(debug,dvb_usb_gp8psk_debug, int, 0644); | ||
22 | MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS); | ||
23 | |||
24 | int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen) | ||
25 | { | ||
26 | int ret = 0,try = 0; | ||
27 | |||
28 | if ((ret = mutex_lock_interruptible(&d->usb_mutex))) | ||
29 | return ret; | ||
30 | |||
31 | while (ret >= 0 && ret != blen && try < 3) { | ||
32 | ret = usb_control_msg(d->udev, | ||
33 | usb_rcvctrlpipe(d->udev,0), | ||
34 | req, | ||
35 | USB_TYPE_VENDOR | USB_DIR_IN, | ||
36 | value,index,b,blen, | ||
37 | 2000); | ||
38 | deb_info("reading number %d (ret: %d)\n",try,ret); | ||
39 | try++; | ||
40 | } | ||
41 | |||
42 | if (ret < 0 || ret != blen) { | ||
43 | warn("usb in operation failed."); | ||
44 | ret = -EIO; | ||
45 | } else | ||
46 | ret = 0; | ||
47 | |||
48 | deb_xfer("in: req. %x, val: %x, ind: %x, buffer: ",req,value,index); | ||
49 | debug_dump(b,blen,deb_xfer); | ||
50 | |||
51 | mutex_unlock(&d->usb_mutex); | ||
52 | |||
53 | return ret; | ||
54 | } | ||
55 | |||
56 | int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, | ||
57 | u16 index, u8 *b, int blen) | ||
58 | { | ||
59 | int ret; | ||
60 | |||
61 | deb_xfer("out: req. %x, val: %x, ind: %x, buffer: ",req,value,index); | ||
62 | debug_dump(b,blen,deb_xfer); | ||
63 | |||
64 | if ((ret = mutex_lock_interruptible(&d->usb_mutex))) | ||
65 | return ret; | ||
66 | |||
67 | if (usb_control_msg(d->udev, | ||
68 | usb_sndctrlpipe(d->udev,0), | ||
69 | req, | ||
70 | USB_TYPE_VENDOR | USB_DIR_OUT, | ||
71 | value,index,b,blen, | ||
72 | 2000) != blen) { | ||
73 | warn("usb out operation failed."); | ||
74 | ret = -EIO; | ||
75 | } else | ||
76 | ret = 0; | ||
77 | mutex_unlock(&d->usb_mutex); | ||
78 | |||
79 | return ret; | ||
80 | } | ||
81 | |||
82 | static int gp8psk_load_bcm4500fw(struct dvb_usb_device *d) | ||
83 | { | ||
84 | int ret; | ||
85 | const struct firmware *fw = NULL; | ||
86 | u8 *ptr, *buf; | ||
87 | if ((ret = request_firmware(&fw, bcm4500_firmware, | ||
88 | &d->udev->dev)) != 0) { | ||
89 | err("did not find the bcm4500 firmware file. (%s) " | ||
90 | "Please see linux/Documentation/dvb/ for more details on firmware-problems. (%d)", | ||
91 | bcm4500_firmware,ret); | ||
92 | return ret; | ||
93 | } | ||
94 | |||
95 | ret = -EINVAL; | ||
96 | |||
97 | if (gp8psk_usb_out_op(d, LOAD_BCM4500,1,0,NULL, 0)) | ||
98 | goto out_rel_fw; | ||
99 | |||
100 | info("downloaidng bcm4500 firmware from file '%s'",bcm4500_firmware); | ||
101 | |||
102 | ptr = fw->data; | ||
103 | buf = kmalloc(512, GFP_KERNEL | GFP_DMA); | ||
104 | |||
105 | while (ptr[0] != 0xff) { | ||
106 | u16 buflen = ptr[0] + 4; | ||
107 | if (ptr + buflen >= fw->data + fw->size) { | ||
108 | err("failed to load bcm4500 firmware."); | ||
109 | goto out_free; | ||
110 | } | ||
111 | memcpy(buf, ptr, buflen); | ||
112 | if (dvb_usb_generic_write(d, buf, buflen)) { | ||
113 | err("failed to load bcm4500 firmware."); | ||
114 | goto out_free; | ||
115 | } | ||
116 | ptr += buflen; | ||
117 | } | ||
118 | |||
119 | ret = 0; | ||
120 | |||
121 | out_free: | ||
122 | kfree(buf); | ||
123 | out_rel_fw: | ||
124 | release_firmware(fw); | ||
125 | |||
126 | return ret; | ||
127 | } | ||
128 | |||
129 | static int gp8psk_power_ctrl(struct dvb_usb_device *d, int onoff) | ||
130 | { | ||
131 | u8 status, buf; | ||
132 | if (onoff) { | ||
133 | gp8psk_usb_in_op(d, GET_8PSK_CONFIG,0,0,&status,1); | ||
134 | if (! (status & 0x01)) /* started */ | ||
135 | if (gp8psk_usb_in_op(d, BOOT_8PSK, 1, 0, &buf, 1)) | ||
136 | return -EINVAL; | ||
137 | |||
138 | if (! (status & 0x02)) /* BCM4500 firmware loaded */ | ||
139 | if(gp8psk_load_bcm4500fw(d)) | ||
140 | return EINVAL; | ||
141 | |||
142 | if (! (status & 0x04)) /* LNB Power */ | ||
143 | if (gp8psk_usb_in_op(d, START_INTERSIL, 1, 0, | ||
144 | &buf, 1)) | ||
145 | return EINVAL; | ||
146 | |||
147 | /* Set DVB mode */ | ||
148 | if(gp8psk_usb_out_op(d, SET_DVB_MODE, 1, 0, NULL, 0)) | ||
149 | return -EINVAL; | ||
150 | gp8psk_usb_in_op(d, GET_8PSK_CONFIG,0,0,&status,1); | ||
151 | } else { | ||
152 | /* Turn off LNB power */ | ||
153 | if (gp8psk_usb_in_op(d, START_INTERSIL, 0, 0, &buf, 1)) | ||
154 | return EINVAL; | ||
155 | /* Turn off 8psk power */ | ||
156 | if (gp8psk_usb_in_op(d, BOOT_8PSK, 0, 0, &buf, 1)) | ||
157 | return -EINVAL; | ||
158 | |||
159 | } | ||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | |||
164 | static int gp8psk_streaming_ctrl(struct dvb_usb_device *d, int onoff) | ||
165 | { | ||
166 | return gp8psk_usb_out_op(d, ARM_TRANSFER, onoff, 0 , NULL, 0); | ||
167 | } | ||
168 | |||
169 | static int gp8psk_frontend_attach(struct dvb_usb_device *d) | ||
170 | { | ||
171 | d->fe = gp8psk_fe_attach(d); | ||
172 | |||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | static struct dvb_usb_properties gp8psk_properties; | ||
177 | |||
178 | static int gp8psk_usb_probe(struct usb_interface *intf, | ||
179 | const struct usb_device_id *id) | ||
180 | { | ||
181 | return dvb_usb_device_init(intf,&gp8psk_properties,THIS_MODULE,NULL); | ||
182 | } | ||
183 | |||
184 | static struct usb_device_id gp8psk_usb_table [] = { | ||
185 | { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_COLD) }, | ||
186 | { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_WARM) }, | ||
187 | { 0 }, | ||
188 | }; | ||
189 | MODULE_DEVICE_TABLE(usb, gp8psk_usb_table); | ||
190 | |||
191 | static struct dvb_usb_properties gp8psk_properties = { | ||
192 | .caps = 0, | ||
193 | |||
194 | .usb_ctrl = CYPRESS_FX2, | ||
195 | .firmware = "dvb-usb-gp8psk-01.fw", | ||
196 | |||
197 | .streaming_ctrl = gp8psk_streaming_ctrl, | ||
198 | .power_ctrl = gp8psk_power_ctrl, | ||
199 | .frontend_attach = gp8psk_frontend_attach, | ||
200 | |||
201 | .generic_bulk_ctrl_endpoint = 0x01, | ||
202 | /* parameter for the MPEG2-data transfer */ | ||
203 | .urb = { | ||
204 | .type = DVB_USB_BULK, | ||
205 | .count = 7, | ||
206 | .endpoint = 0x82, | ||
207 | .u = { | ||
208 | .bulk = { | ||
209 | .buffersize = 8192, | ||
210 | } | ||
211 | } | ||
212 | }, | ||
213 | |||
214 | .num_device_descs = 1, | ||
215 | .devices = { | ||
216 | { .name = "Genpix 8PSK-USB DVB-S USB2.0 receiver", | ||
217 | .cold_ids = { &gp8psk_usb_table[0], NULL }, | ||
218 | .warm_ids = { &gp8psk_usb_table[1], NULL }, | ||
219 | }, | ||
220 | { 0 }, | ||
221 | } | ||
222 | }; | ||
223 | |||
224 | /* usb specific object needed to register this driver with the usb subsystem */ | ||
225 | static struct usb_driver gp8psk_usb_driver = { | ||
226 | .name = "dvb_usb_gp8psk", | ||
227 | .probe = gp8psk_usb_probe, | ||
228 | .disconnect = dvb_usb_device_exit, | ||
229 | .id_table = gp8psk_usb_table, | ||
230 | }; | ||
231 | |||
232 | /* module stuff */ | ||
233 | static int __init gp8psk_usb_module_init(void) | ||
234 | { | ||
235 | int result; | ||
236 | if ((result = usb_register(&gp8psk_usb_driver))) { | ||
237 | err("usb_register failed. (%d)",result); | ||
238 | return result; | ||
239 | } | ||
240 | |||
241 | return 0; | ||
242 | } | ||
243 | |||
244 | static void __exit gp8psk_usb_module_exit(void) | ||
245 | { | ||
246 | /* deregister this driver from the USB subsystem */ | ||
247 | usb_deregister(&gp8psk_usb_driver); | ||
248 | } | ||
249 | |||
250 | module_init(gp8psk_usb_module_init); | ||
251 | module_exit(gp8psk_usb_module_exit); | ||
252 | |||
253 | MODULE_AUTHOR("Alan Nisota <alannisota@gamil.com>"); | ||
254 | MODULE_DESCRIPTION("Driver for Genpix 8psk-USB DVB-S USB2.0"); | ||
255 | MODULE_VERSION("1.0"); | ||
256 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/dvb-usb/gp8psk.h b/drivers/media/dvb/dvb-usb/gp8psk.h new file mode 100644 index 000000000000..3eba7061011c --- /dev/null +++ b/drivers/media/dvb/dvb-usb/gp8psk.h | |||
@@ -0,0 +1,79 @@ | |||
1 | /* DVB USB compliant Linux driver for the | ||
2 | * - GENPIX 8pks/qpsk USB2.0 DVB-S module | ||
3 | * | ||
4 | * Copyright (C) 2006 Alan Nisota (alannisota@gmail.com) | ||
5 | * | ||
6 | * Thanks to GENPIX for the sample code used to implement this module. | ||
7 | * | ||
8 | * This module is based off the vp7045 and vp702x modules | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the Free | ||
12 | * Software Foundation, version 2. | ||
13 | * | ||
14 | * see Documentation/dvb/README.dvb-usb for more information | ||
15 | */ | ||
16 | #ifndef _DVB_USB_GP8PSK_H_ | ||
17 | #define _DVB_USB_GP8PSK_H_ | ||
18 | |||
19 | #define DVB_USB_LOG_PREFIX "gp8psk" | ||
20 | #include "dvb-usb.h" | ||
21 | |||
22 | extern int dvb_usb_gp8psk_debug; | ||
23 | #define deb_info(args...) dprintk(dvb_usb_gp8psk_debug,0x01,args) | ||
24 | #define deb_xfer(args...) dprintk(dvb_usb_gp8psk_debug,0x02,args) | ||
25 | #define deb_rc(args...) dprintk(dvb_usb_gp8psk_debug,0x04,args) | ||
26 | #define deb_fe(args...) dprintk(dvb_usb_gp8psk_debug,0x08,args) | ||
27 | /* gp8psk commands */ | ||
28 | |||
29 | /* Twinhan Vendor requests */ | ||
30 | #define TH_COMMAND_IN 0xC0 | ||
31 | #define TH_COMMAND_OUT 0xC1 | ||
32 | |||
33 | /* command bytes */ | ||
34 | #define GET_8PSK_CONFIG 0x80 | ||
35 | #define SET_8PSK_CONFIG 0x81 | ||
36 | #define ARM_TRANSFER 0x85 | ||
37 | #define TUNE_8PSK 0x86 | ||
38 | #define GET_SIGNAL_STRENGTH 0x87 | ||
39 | #define LOAD_BCM4500 0x88 | ||
40 | #define BOOT_8PSK 0x89 | ||
41 | #define START_INTERSIL 0x8A | ||
42 | #define SET_LNB_VOLTAGE 0x8B | ||
43 | #define SET_22KHZ_TONE 0x8C | ||
44 | #define SEND_DISEQC_COMMAND 0x8D | ||
45 | #define SET_DVB_MODE 0x8E | ||
46 | #define SET_DN_SWITCH 0x8F | ||
47 | #define GET_SIGNAL_LOCK 0x90 | ||
48 | |||
49 | /* Satellite modulation modes */ | ||
50 | #define ADV_MOD_DVB_QPSK 0 /* DVB-S QPSK */ | ||
51 | #define ADV_MOD_TURBO_QPSK 1 /* Turbo QPSK */ | ||
52 | #define ADV_MOD_TURBO_8PSK 2 /* Turbo 8PSK (also used for Trellis 8PSK) */ | ||
53 | #define ADV_MOD_TURBO_16QAM 3 /* Turbo 16QAM (also used for Trellis 8PSK) */ | ||
54 | |||
55 | #define ADV_MOD_DCII_C_QPSK 4 /* Digicipher II Combo */ | ||
56 | #define ADV_MOD_DCII_I_QPSK 5 /* Digicipher II I-stream */ | ||
57 | #define ADV_MOD_DCII_Q_QPSK 6 /* Digicipher II Q-stream */ | ||
58 | #define ADV_MOD_DCII_C_OQPSK 7 /* Digicipher II offset QPSK */ | ||
59 | #define ADV_MOD_DSS_QPSK 8 /* DSS (DIRECTV) QPSK */ | ||
60 | #define ADV_MOD_DVB_BPSK 9 /* DVB-S BPSK */ | ||
61 | |||
62 | #define GET_USB_SPEED 0x07 | ||
63 | #define USB_SPEED_LOW 0 | ||
64 | #define USB_SPEED_FULL 1 | ||
65 | #define USB_SPEED_HIGH 2 | ||
66 | |||
67 | #define RESET_FX2 0x13 | ||
68 | |||
69 | #define FW_VERSION_READ 0x0B | ||
70 | #define VENDOR_STRING_READ 0x0C | ||
71 | #define PRODUCT_STRING_READ 0x0D | ||
72 | #define FW_BCD_VERSION_READ 0x14 | ||
73 | |||
74 | extern struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d); | ||
75 | extern int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen); | ||
76 | extern int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, | ||
77 | u16 index, u8 *b, int blen); | ||
78 | |||
79 | #endif | ||
diff --git a/drivers/media/dvb/dvb-usb/umt-010.c b/drivers/media/dvb/dvb-usb/umt-010.c index 14f1911c79bb..97d74da0dad8 100644 --- a/drivers/media/dvb/dvb-usb/umt-010.c +++ b/drivers/media/dvb/dvb-usb/umt-010.c | |||
@@ -57,7 +57,6 @@ static int umt_mt352_frontend_attach(struct dvb_usb_device *d) | |||
57 | memset(&umt_config,0,sizeof(struct mt352_config)); | 57 | memset(&umt_config,0,sizeof(struct mt352_config)); |
58 | umt_config.demod_init = umt_mt352_demod_init; | 58 | umt_config.demod_init = umt_mt352_demod_init; |
59 | umt_config.demod_address = 0xf; | 59 | umt_config.demod_address = 0xf; |
60 | umt_config.pll_set = dvb_usb_pll_set; | ||
61 | 60 | ||
62 | d->fe = mt352_attach(&umt_config, &d->i2c_adap); | 61 | d->fe = mt352_attach(&umt_config, &d->i2c_adap); |
63 | 62 | ||
@@ -68,6 +67,7 @@ static int umt_tuner_attach (struct dvb_usb_device *d) | |||
68 | { | 67 | { |
69 | d->pll_addr = 0x61; | 68 | d->pll_addr = 0x61; |
70 | d->pll_desc = &dvb_pll_tua6034; | 69 | d->pll_desc = &dvb_pll_tua6034; |
70 | d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs; | ||
71 | return 0; | 71 | return 0; |
72 | } | 72 | } |
73 | 73 | ||
diff --git a/drivers/media/dvb/dvb-usb/vp702x-fe.c b/drivers/media/dvb/dvb-usb/vp702x-fe.c index 2a89f8c5da99..d4da494132ec 100644 --- a/drivers/media/dvb/dvb-usb/vp702x-fe.c +++ b/drivers/media/dvb/dvb-usb/vp702x-fe.c | |||
@@ -287,17 +287,16 @@ struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d) | |||
287 | goto error; | 287 | goto error; |
288 | 288 | ||
289 | s->d = d; | 289 | s->d = d; |
290 | s->fe.ops = &vp702x_fe_ops; | 290 | |
291 | memcpy(&s->fe.ops,&vp702x_fe_ops,sizeof(struct dvb_frontend_ops)); | ||
291 | s->fe.demodulator_priv = s; | 292 | s->fe.demodulator_priv = s; |
292 | 293 | ||
293 | s->lnb_buf[1] = SET_LNB_POWER; | 294 | s->lnb_buf[1] = SET_LNB_POWER; |
294 | s->lnb_buf[3] = 0xff; /* 0=tone burst, 2=data burst, ff=off */ | 295 | s->lnb_buf[3] = 0xff; /* 0=tone burst, 2=data burst, ff=off */ |
295 | 296 | ||
296 | goto success; | 297 | return &s->fe; |
297 | error: | 298 | error: |
298 | return NULL; | 299 | return NULL; |
299 | success: | ||
300 | return &s->fe; | ||
301 | } | 300 | } |
302 | 301 | ||
303 | 302 | ||
diff --git a/drivers/media/dvb/dvb-usb/vp7045-fe.c b/drivers/media/dvb/dvb-usb/vp7045-fe.c index 9999336aeeb6..8452eef90322 100644 --- a/drivers/media/dvb/dvb-usb/vp7045-fe.c +++ b/drivers/media/dvb/dvb-usb/vp7045-fe.c | |||
@@ -23,8 +23,6 @@ | |||
23 | 23 | ||
24 | struct vp7045_fe_state { | 24 | struct vp7045_fe_state { |
25 | struct dvb_frontend fe; | 25 | struct dvb_frontend fe; |
26 | struct dvb_frontend_ops ops; | ||
27 | |||
28 | struct dvb_usb_device *d; | 26 | struct dvb_usb_device *d; |
29 | }; | 27 | }; |
30 | 28 | ||
@@ -151,15 +149,12 @@ struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d) | |||
151 | goto error; | 149 | goto error; |
152 | 150 | ||
153 | s->d = d; | 151 | s->d = d; |
154 | memcpy(&s->ops, &vp7045_fe_ops, sizeof(struct dvb_frontend_ops)); | 152 | memcpy(&s->fe.ops, &vp7045_fe_ops, sizeof(struct dvb_frontend_ops)); |
155 | s->fe.ops = &s->ops; | ||
156 | s->fe.demodulator_priv = s; | 153 | s->fe.demodulator_priv = s; |
157 | 154 | ||
158 | goto success; | 155 | return &s->fe; |
159 | error: | 156 | error: |
160 | return NULL; | 157 | return NULL; |
161 | success: | ||
162 | return &s->fe; | ||
163 | } | 158 | } |
164 | 159 | ||
165 | 160 | ||
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index 37d5e0af1683..0ef361f0309b 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig | |||
@@ -157,7 +157,7 @@ config DVB_STV0297 | |||
157 | help | 157 | help |
158 | A DVB-C tuner module. Say Y when you want to support this frontend. | 158 | A DVB-C tuner module. Say Y when you want to support this frontend. |
159 | 159 | ||
160 | comment "ATSC (North American/Korean Terresterial DTV) frontends" | 160 | comment "ATSC (North American/Korean Terrestrial/Cable DTV) frontends" |
161 | depends on DVB_CORE | 161 | depends on DVB_CORE |
162 | 162 | ||
163 | config DVB_NXT200X | 163 | config DVB_NXT200X |
@@ -216,4 +216,20 @@ config DVB_LGDT330X | |||
216 | An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want | 216 | An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want |
217 | to support this frontend. | 217 | to support this frontend. |
218 | 218 | ||
219 | |||
220 | comment "Miscellaneous devices" | ||
221 | depends on DVB_CORE | ||
222 | |||
223 | config DVB_LNBP21 | ||
224 | tristate "LNBP21 SEC controller" | ||
225 | depends on DVB_CORE | ||
226 | help | ||
227 | An SEC control chip. | ||
228 | |||
229 | config DVB_ISL6421 | ||
230 | tristate "ISL6421 SEC controller" | ||
231 | depends on DVB_CORE | ||
232 | help | ||
233 | An SEC control chip. | ||
234 | |||
219 | endmenu | 235 | endmenu |
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index d09b6071fbaf..5222245c7f59 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile | |||
@@ -31,3 +31,5 @@ obj-$(CONFIG_DVB_BCM3510) += bcm3510.o | |||
31 | obj-$(CONFIG_DVB_S5H1420) += s5h1420.o | 31 | obj-$(CONFIG_DVB_S5H1420) += s5h1420.o |
32 | obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o | 32 | obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o |
33 | obj-$(CONFIG_DVB_CX24123) += cx24123.o | 33 | obj-$(CONFIG_DVB_CX24123) += cx24123.o |
34 | obj-$(CONFIG_DVB_LNBP21) += lnbp21.o | ||
35 | obj-$(CONFIG_DVB_ISL6421) += isl6421.o | ||
diff --git a/drivers/media/dvb/frontends/bcm3510.c b/drivers/media/dvb/frontends/bcm3510.c index 1708a1d4893e..baeb311de893 100644 --- a/drivers/media/dvb/frontends/bcm3510.c +++ b/drivers/media/dvb/frontends/bcm3510.c | |||
@@ -48,7 +48,6 @@ | |||
48 | struct bcm3510_state { | 48 | struct bcm3510_state { |
49 | 49 | ||
50 | struct i2c_adapter* i2c; | 50 | struct i2c_adapter* i2c; |
51 | struct dvb_frontend_ops ops; | ||
52 | const struct bcm3510_config* config; | 51 | const struct bcm3510_config* config; |
53 | struct dvb_frontend frontend; | 52 | struct dvb_frontend frontend; |
54 | 53 | ||
@@ -791,10 +790,9 @@ struct dvb_frontend* bcm3510_attach(const struct bcm3510_config *config, | |||
791 | 790 | ||
792 | state->config = config; | 791 | state->config = config; |
793 | state->i2c = i2c; | 792 | state->i2c = i2c; |
794 | memcpy(&state->ops, &bcm3510_ops, sizeof(struct dvb_frontend_ops)); | ||
795 | 793 | ||
796 | /* create dvb_frontend */ | 794 | /* create dvb_frontend */ |
797 | state->frontend.ops = &state->ops; | 795 | memcpy(&state->frontend.ops, &bcm3510_ops, sizeof(struct dvb_frontend_ops)); |
798 | state->frontend.demodulator_priv = state; | 796 | state->frontend.demodulator_priv = state; |
799 | 797 | ||
800 | mutex_init(&state->hab_mutex); | 798 | mutex_init(&state->hab_mutex); |
diff --git a/drivers/media/dvb/frontends/bsbe1.h b/drivers/media/dvb/frontends/bsbe1.h index 78573b22ada9..d8f65738e5d2 100644 --- a/drivers/media/dvb/frontends/bsbe1.h +++ b/drivers/media/dvb/frontends/bsbe1.h | |||
@@ -89,12 +89,13 @@ static int alps_bsbe1_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ra | |||
89 | return 0; | 89 | return 0; |
90 | } | 90 | } |
91 | 91 | ||
92 | static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params) | 92 | static int alps_bsbe1_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) |
93 | { | 93 | { |
94 | int ret; | 94 | int ret; |
95 | u8 data[4]; | 95 | u8 data[4]; |
96 | u32 div; | 96 | u32 div; |
97 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; | 97 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; |
98 | struct i2c_adapter *i2c = fe->tuner_priv; | ||
98 | 99 | ||
99 | if ((params->frequency < 950000) || (params->frequency > 2150000)) | 100 | if ((params->frequency < 950000) || (params->frequency > 2150000)) |
100 | return -EINVAL; | 101 | return -EINVAL; |
@@ -105,6 +106,8 @@ static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, | |||
105 | data[2] = 0x80 | ((div & 0x18000) >> 10) | 4; | 106 | data[2] = 0x80 | ((div & 0x18000) >> 10) | 4; |
106 | data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4; | 107 | data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4; |
107 | 108 | ||
109 | if (fe->ops.i2c_gate_ctrl) | ||
110 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
108 | ret = i2c_transfer(i2c, &msg, 1); | 111 | ret = i2c_transfer(i2c, &msg, 1); |
109 | return (ret != 1) ? -EIO : 0; | 112 | return (ret != 1) ? -EIO : 0; |
110 | } | 113 | } |
@@ -117,7 +120,6 @@ static struct stv0299_config alps_bsbe1_config = { | |||
117 | .skip_reinit = 0, | 120 | .skip_reinit = 0, |
118 | .min_delay_ms = 100, | 121 | .min_delay_ms = 100, |
119 | .set_symbol_rate = alps_bsbe1_set_symbol_rate, | 122 | .set_symbol_rate = alps_bsbe1_set_symbol_rate, |
120 | .pll_set = alps_bsbe1_pll_set, | ||
121 | }; | 123 | }; |
122 | 124 | ||
123 | #endif | 125 | #endif |
diff --git a/drivers/media/dvb/frontends/bsru6.h b/drivers/media/dvb/frontends/bsru6.h index 2a5366ce79cc..e231cd84b3a1 100644 --- a/drivers/media/dvb/frontends/bsru6.h +++ b/drivers/media/dvb/frontends/bsru6.h | |||
@@ -101,11 +101,12 @@ static int alps_bsru6_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ra | |||
101 | return 0; | 101 | return 0; |
102 | } | 102 | } |
103 | 103 | ||
104 | static int alps_bsru6_pll_set(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters *params) | 104 | static int alps_bsru6_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) |
105 | { | 105 | { |
106 | u8 buf[4]; | 106 | u8 buf[4]; |
107 | u32 div; | 107 | u32 div; |
108 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; | 108 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; |
109 | struct i2c_adapter *i2c = fe->tuner_priv; | ||
109 | 110 | ||
110 | if ((params->frequency < 950000) || (params->frequency > 2150000)) | 111 | if ((params->frequency < 950000) || (params->frequency > 2150000)) |
111 | return -EINVAL; | 112 | return -EINVAL; |
@@ -119,6 +120,8 @@ static int alps_bsru6_pll_set(struct dvb_frontend *fe, struct i2c_adapter *i2c, | |||
119 | if (params->frequency > 1530000) | 120 | if (params->frequency > 1530000) |
120 | buf[3] = 0xc0; | 121 | buf[3] = 0xc0; |
121 | 122 | ||
123 | if (fe->ops.i2c_gate_ctrl) | ||
124 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
122 | if (i2c_transfer(i2c, &msg, 1) != 1) | 125 | if (i2c_transfer(i2c, &msg, 1) != 1) |
123 | return -EIO; | 126 | return -EIO; |
124 | return 0; | 127 | return 0; |
@@ -134,7 +137,6 @@ static struct stv0299_config alps_bsru6_config = { | |||
134 | .volt13_op0_op1 = STV0299_VOLT13_OP1, | 137 | .volt13_op0_op1 = STV0299_VOLT13_OP1, |
135 | .min_delay_ms = 100, | 138 | .min_delay_ms = 100, |
136 | .set_symbol_rate = alps_bsru6_set_symbol_rate, | 139 | .set_symbol_rate = alps_bsru6_set_symbol_rate, |
137 | .pll_set = alps_bsru6_pll_set, | ||
138 | }; | 140 | }; |
139 | 141 | ||
140 | #endif | 142 | #endif |
diff --git a/drivers/media/dvb/frontends/cx22700.c b/drivers/media/dvb/frontends/cx22700.c index 755f774f6b7d..3c7c09a362b2 100644 --- a/drivers/media/dvb/frontends/cx22700.c +++ b/drivers/media/dvb/frontends/cx22700.c | |||
@@ -34,8 +34,6 @@ struct cx22700_state { | |||
34 | 34 | ||
35 | struct i2c_adapter* i2c; | 35 | struct i2c_adapter* i2c; |
36 | 36 | ||
37 | struct dvb_frontend_ops ops; | ||
38 | |||
39 | const struct cx22700_config* config; | 37 | const struct cx22700_config* config; |
40 | 38 | ||
41 | struct dvb_frontend frontend; | 39 | struct dvb_frontend frontend; |
@@ -247,12 +245,6 @@ static int cx22700_init (struct dvb_frontend* fe) | |||
247 | 245 | ||
248 | cx22700_writereg (state, 0x00, 0x01); | 246 | cx22700_writereg (state, 0x00, 0x01); |
249 | 247 | ||
250 | if (state->config->pll_init) { | ||
251 | cx22700_writereg (state, 0x0a, 0x00); /* open i2c bus switch */ | ||
252 | state->config->pll_init(fe); | ||
253 | cx22700_writereg (state, 0x0a, 0x01); /* close i2c bus switch */ | ||
254 | } | ||
255 | |||
256 | return 0; | 248 | return 0; |
257 | } | 249 | } |
258 | 250 | ||
@@ -333,9 +325,11 @@ static int cx22700_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par | |||
333 | cx22700_writereg (state, 0x00, 0x02); /* XXX CHECKME: soft reset*/ | 325 | cx22700_writereg (state, 0x00, 0x02); /* XXX CHECKME: soft reset*/ |
334 | cx22700_writereg (state, 0x00, 0x00); | 326 | cx22700_writereg (state, 0x00, 0x00); |
335 | 327 | ||
336 | cx22700_writereg (state, 0x0a, 0x00); /* open i2c bus switch */ | 328 | if (fe->ops.tuner_ops.set_params) { |
337 | state->config->pll_set(fe, p); | 329 | fe->ops.tuner_ops.set_params(fe, p); |
338 | cx22700_writereg (state, 0x0a, 0x01); /* close i2c bus switch */ | 330 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); |
331 | } | ||
332 | |||
339 | cx22700_set_inversion (state, p->inversion); | 333 | cx22700_set_inversion (state, p->inversion); |
340 | cx22700_set_tps (state, &p->u.ofdm); | 334 | cx22700_set_tps (state, &p->u.ofdm); |
341 | cx22700_writereg (state, 0x37, 0x01); /* PAL loop filter off */ | 335 | cx22700_writereg (state, 0x37, 0x01); /* PAL loop filter off */ |
@@ -353,6 +347,17 @@ static int cx22700_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par | |||
353 | return cx22700_get_tps (state, &p->u.ofdm); | 347 | return cx22700_get_tps (state, &p->u.ofdm); |
354 | } | 348 | } |
355 | 349 | ||
350 | static int cx22700_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) | ||
351 | { | ||
352 | struct cx22700_state* state = fe->demodulator_priv; | ||
353 | |||
354 | if (enable) { | ||
355 | return cx22700_writereg(state, 0x0a, 0x00); | ||
356 | } else { | ||
357 | return cx22700_writereg(state, 0x0a, 0x01); | ||
358 | } | ||
359 | } | ||
360 | |||
356 | static int cx22700_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) | 361 | static int cx22700_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) |
357 | { | 362 | { |
358 | fesettings->min_delay_ms = 150; | 363 | fesettings->min_delay_ms = 150; |
@@ -381,13 +386,12 @@ struct dvb_frontend* cx22700_attach(const struct cx22700_config* config, | |||
381 | /* setup the state */ | 386 | /* setup the state */ |
382 | state->config = config; | 387 | state->config = config; |
383 | state->i2c = i2c; | 388 | state->i2c = i2c; |
384 | memcpy(&state->ops, &cx22700_ops, sizeof(struct dvb_frontend_ops)); | ||
385 | 389 | ||
386 | /* check if the demod is there */ | 390 | /* check if the demod is there */ |
387 | if (cx22700_readreg(state, 0x07) < 0) goto error; | 391 | if (cx22700_readreg(state, 0x07) < 0) goto error; |
388 | 392 | ||
389 | /* create dvb_frontend */ | 393 | /* create dvb_frontend */ |
390 | state->frontend.ops = &state->ops; | 394 | memcpy(&state->frontend.ops, &cx22700_ops, sizeof(struct dvb_frontend_ops)); |
391 | state->frontend.demodulator_priv = state; | 395 | state->frontend.demodulator_priv = state; |
392 | return &state->frontend; | 396 | return &state->frontend; |
393 | 397 | ||
@@ -413,6 +417,7 @@ static struct dvb_frontend_ops cx22700_ops = { | |||
413 | .release = cx22700_release, | 417 | .release = cx22700_release, |
414 | 418 | ||
415 | .init = cx22700_init, | 419 | .init = cx22700_init, |
420 | .i2c_gate_ctrl = cx22700_i2c_gate_ctrl, | ||
416 | 421 | ||
417 | .set_frontend = cx22700_set_frontend, | 422 | .set_frontend = cx22700_set_frontend, |
418 | .get_frontend = cx22700_get_frontend, | 423 | .get_frontend = cx22700_get_frontend, |
diff --git a/drivers/media/dvb/frontends/cx22700.h b/drivers/media/dvb/frontends/cx22700.h index c9145b45874b..dcd8979c1a15 100644 --- a/drivers/media/dvb/frontends/cx22700.h +++ b/drivers/media/dvb/frontends/cx22700.h | |||
@@ -29,10 +29,6 @@ struct cx22700_config | |||
29 | { | 29 | { |
30 | /* the demodulator's i2c address */ | 30 | /* the demodulator's i2c address */ |
31 | u8 demod_address; | 31 | u8 demod_address; |
32 | |||
33 | /* PLL maintenance */ | ||
34 | int (*pll_init)(struct dvb_frontend* fe); | ||
35 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
36 | }; | 32 | }; |
37 | 33 | ||
38 | extern struct dvb_frontend* cx22700_attach(const struct cx22700_config* config, | 34 | extern struct dvb_frontend* cx22700_attach(const struct cx22700_config* config, |
diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c index 0fc899f81c5e..4106d46c957f 100644 --- a/drivers/media/dvb/frontends/cx22702.c +++ b/drivers/media/dvb/frontends/cx22702.c | |||
@@ -40,8 +40,6 @@ struct cx22702_state { | |||
40 | 40 | ||
41 | struct i2c_adapter* i2c; | 41 | struct i2c_adapter* i2c; |
42 | 42 | ||
43 | struct dvb_frontend_ops ops; | ||
44 | |||
45 | /* configuration settings */ | 43 | /* configuration settings */ |
46 | const struct cx22702_config* config; | 44 | const struct cx22702_config* config; |
47 | 45 | ||
@@ -211,22 +209,10 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet | |||
211 | u8 val; | 209 | u8 val; |
212 | struct cx22702_state* state = fe->demodulator_priv; | 210 | struct cx22702_state* state = fe->demodulator_priv; |
213 | 211 | ||
214 | /* set PLL */ | 212 | if (fe->ops.tuner_ops.set_params) { |
215 | cx22702_i2c_gate_ctrl(fe, 1); | 213 | fe->ops.tuner_ops.set_params(fe, p); |
216 | if (state->config->pll_set) { | 214 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); |
217 | state->config->pll_set(fe, p); | ||
218 | } else if (state->config->pll_desc) { | ||
219 | u8 pllbuf[4]; | ||
220 | struct i2c_msg msg = { .addr = state->config->pll_address, | ||
221 | .buf = pllbuf, .len = 4 }; | ||
222 | dvb_pll_configure(state->config->pll_desc, pllbuf, | ||
223 | p->frequency, | ||
224 | p->u.ofdm.bandwidth); | ||
225 | i2c_transfer(state->i2c, &msg, 1); | ||
226 | } else { | ||
227 | BUG(); | ||
228 | } | 215 | } |
229 | cx22702_i2c_gate_ctrl(fe, 0); | ||
230 | 216 | ||
231 | /* set inversion */ | 217 | /* set inversion */ |
232 | cx22702_set_inversion (state, p->inversion); | 218 | cx22702_set_inversion (state, p->inversion); |
@@ -358,10 +344,6 @@ static int cx22702_init (struct dvb_frontend* fe) | |||
358 | 344 | ||
359 | cx22702_writereg (state, 0xf8, (state->config->output_mode << 1) & 0x02); | 345 | cx22702_writereg (state, 0xf8, (state->config->output_mode << 1) & 0x02); |
360 | 346 | ||
361 | /* init PLL */ | ||
362 | if (state->config->pll_init) | ||
363 | state->config->pll_init(fe); | ||
364 | |||
365 | cx22702_i2c_gate_ctrl(fe, 0); | 347 | cx22702_i2c_gate_ctrl(fe, 0); |
366 | 348 | ||
367 | return 0; | 349 | return 0; |
@@ -495,7 +477,6 @@ struct dvb_frontend* cx22702_attach(const struct cx22702_config* config, | |||
495 | /* setup the state */ | 477 | /* setup the state */ |
496 | state->config = config; | 478 | state->config = config; |
497 | state->i2c = i2c; | 479 | state->i2c = i2c; |
498 | memcpy(&state->ops, &cx22702_ops, sizeof(struct dvb_frontend_ops)); | ||
499 | state->prevUCBlocks = 0; | 480 | state->prevUCBlocks = 0; |
500 | 481 | ||
501 | /* check if the demod is there */ | 482 | /* check if the demod is there */ |
@@ -503,7 +484,7 @@ struct dvb_frontend* cx22702_attach(const struct cx22702_config* config, | |||
503 | goto error; | 484 | goto error; |
504 | 485 | ||
505 | /* create dvb_frontend */ | 486 | /* create dvb_frontend */ |
506 | state->frontend.ops = &state->ops; | 487 | memcpy(&state->frontend.ops, &cx22702_ops, sizeof(struct dvb_frontend_ops)); |
507 | state->frontend.demodulator_priv = state; | 488 | state->frontend.demodulator_priv = state; |
508 | return &state->frontend; | 489 | return &state->frontend; |
509 | 490 | ||
@@ -530,6 +511,7 @@ static struct dvb_frontend_ops cx22702_ops = { | |||
530 | .release = cx22702_release, | 511 | .release = cx22702_release, |
531 | 512 | ||
532 | .init = cx22702_init, | 513 | .init = cx22702_init, |
514 | .i2c_gate_ctrl = cx22702_i2c_gate_ctrl, | ||
533 | 515 | ||
534 | .set_frontend = cx22702_set_tps, | 516 | .set_frontend = cx22702_set_tps, |
535 | .get_frontend = cx22702_get_frontend, | 517 | .get_frontend = cx22702_get_frontend, |
@@ -540,7 +522,6 @@ static struct dvb_frontend_ops cx22702_ops = { | |||
540 | .read_signal_strength = cx22702_read_signal_strength, | 522 | .read_signal_strength = cx22702_read_signal_strength, |
541 | .read_snr = cx22702_read_snr, | 523 | .read_snr = cx22702_read_snr, |
542 | .read_ucblocks = cx22702_read_ucblocks, | 524 | .read_ucblocks = cx22702_read_ucblocks, |
543 | .i2c_gate_ctrl = cx22702_i2c_gate_ctrl, | ||
544 | }; | 525 | }; |
545 | 526 | ||
546 | module_param(debug, int, 0644); | 527 | module_param(debug, int, 0644); |
diff --git a/drivers/media/dvb/frontends/cx22702.h b/drivers/media/dvb/frontends/cx22702.h index 5633976a58f1..7f2f241e5d44 100644 --- a/drivers/media/dvb/frontends/cx22702.h +++ b/drivers/media/dvb/frontends/cx22702.h | |||
@@ -39,13 +39,6 @@ struct cx22702_config | |||
39 | #define CX22702_PARALLEL_OUTPUT 0 | 39 | #define CX22702_PARALLEL_OUTPUT 0 |
40 | #define CX22702_SERIAL_OUTPUT 1 | 40 | #define CX22702_SERIAL_OUTPUT 1 |
41 | u8 output_mode; | 41 | u8 output_mode; |
42 | |||
43 | /* PLL maintenance */ | ||
44 | u8 pll_address; | ||
45 | struct dvb_pll_desc *pll_desc; | ||
46 | |||
47 | int (*pll_init)(struct dvb_frontend* fe); | ||
48 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
49 | }; | 42 | }; |
50 | 43 | ||
51 | extern struct dvb_frontend* cx22702_attach(const struct cx22702_config* config, | 44 | extern struct dvb_frontend* cx22702_attach(const struct cx22702_config* config, |
diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c index f3edf8b517dd..ce3c7398bac9 100644 --- a/drivers/media/dvb/frontends/cx24110.c +++ b/drivers/media/dvb/frontends/cx24110.c | |||
@@ -36,8 +36,6 @@ struct cx24110_state { | |||
36 | 36 | ||
37 | struct i2c_adapter* i2c; | 37 | struct i2c_adapter* i2c; |
38 | 38 | ||
39 | struct dvb_frontend_ops ops; | ||
40 | |||
41 | const struct cx24110_config* config; | 39 | const struct cx24110_config* config; |
42 | 40 | ||
43 | struct dvb_frontend frontend; | 41 | struct dvb_frontend frontend; |
@@ -250,7 +248,7 @@ static int cx24110_set_symbolrate (struct cx24110_state* state, u32 srate) | |||
250 | static const u32 bands[]={5000000UL,15000000UL,90999000UL/2}; | 248 | static const u32 bands[]={5000000UL,15000000UL,90999000UL/2}; |
251 | int i; | 249 | int i; |
252 | 250 | ||
253 | dprintk("cx24110 debug: entering %s(%d)\n",__FUNCTION__,srate); | 251 | dprintk("cx24110 debug: entering %s(%d)\n",__FUNCTION__,srate); |
254 | if (srate>90999000UL/2) | 252 | if (srate>90999000UL/2) |
255 | srate=90999000UL/2; | 253 | srate=90999000UL/2; |
256 | if (srate<500000) | 254 | if (srate<500000) |
@@ -366,17 +364,6 @@ static int cx24110_initfe(struct dvb_frontend* fe) | |||
366 | cx24110_writereg(state, cx24110_regdata[i].reg, cx24110_regdata[i].data); | 364 | cx24110_writereg(state, cx24110_regdata[i].reg, cx24110_regdata[i].data); |
367 | }; | 365 | }; |
368 | 366 | ||
369 | if (state->config->pll_init) state->config->pll_init(fe); | ||
370 | |||
371 | return 0; | ||
372 | } | ||
373 | |||
374 | static int cx24110_sleep(struct dvb_frontend *fe) | ||
375 | { | ||
376 | struct cx24110_state *state = fe->demodulator_priv; | ||
377 | |||
378 | if (state->config->pll_sleep) | ||
379 | return state->config->pll_sleep(fe); | ||
380 | return 0; | 367 | return 0; |
381 | } | 368 | } |
382 | 369 | ||
@@ -548,7 +535,12 @@ static int cx24110_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par | |||
548 | { | 535 | { |
549 | struct cx24110_state *state = fe->demodulator_priv; | 536 | struct cx24110_state *state = fe->demodulator_priv; |
550 | 537 | ||
551 | state->config->pll_set(fe, p); | 538 | |
539 | if (fe->ops.tuner_ops.set_params) { | ||
540 | fe->ops.tuner_ops.set_params(fe, p); | ||
541 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); | ||
542 | } | ||
543 | |||
552 | cx24110_set_inversion (state, p->inversion); | 544 | cx24110_set_inversion (state, p->inversion); |
553 | cx24110_set_fec (state, p->u.qpsk.fec_inner); | 545 | cx24110_set_fec (state, p->u.qpsk.fec_inner); |
554 | cx24110_set_symbolrate (state, p->u.qpsk.symbol_rate); | 546 | cx24110_set_symbolrate (state, p->u.qpsk.symbol_rate); |
@@ -612,7 +604,6 @@ struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, | |||
612 | /* setup the state */ | 604 | /* setup the state */ |
613 | state->config = config; | 605 | state->config = config; |
614 | state->i2c = i2c; | 606 | state->i2c = i2c; |
615 | memcpy(&state->ops, &cx24110_ops, sizeof(struct dvb_frontend_ops)); | ||
616 | state->lastber = 0; | 607 | state->lastber = 0; |
617 | state->lastbler = 0; | 608 | state->lastbler = 0; |
618 | state->lastesn0 = 0; | 609 | state->lastesn0 = 0; |
@@ -622,7 +613,7 @@ struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, | |||
622 | if ((ret != 0x5a) && (ret != 0x69)) goto error; | 613 | if ((ret != 0x5a) && (ret != 0x69)) goto error; |
623 | 614 | ||
624 | /* create dvb_frontend */ | 615 | /* create dvb_frontend */ |
625 | state->frontend.ops = &state->ops; | 616 | memcpy(&state->frontend.ops, &cx24110_ops, sizeof(struct dvb_frontend_ops)); |
626 | state->frontend.demodulator_priv = state; | 617 | state->frontend.demodulator_priv = state; |
627 | return &state->frontend; | 618 | return &state->frontend; |
628 | 619 | ||
@@ -651,7 +642,6 @@ static struct dvb_frontend_ops cx24110_ops = { | |||
651 | .release = cx24110_release, | 642 | .release = cx24110_release, |
652 | 643 | ||
653 | .init = cx24110_initfe, | 644 | .init = cx24110_initfe, |
654 | .sleep = cx24110_sleep, | ||
655 | .set_frontend = cx24110_set_frontend, | 645 | .set_frontend = cx24110_set_frontend, |
656 | .get_frontend = cx24110_get_frontend, | 646 | .get_frontend = cx24110_get_frontend, |
657 | .read_status = cx24110_read_status, | 647 | .read_status = cx24110_read_status, |
diff --git a/drivers/media/dvb/frontends/cx24110.h b/drivers/media/dvb/frontends/cx24110.h index 609ac642b406..b354a64e0e74 100644 --- a/drivers/media/dvb/frontends/cx24110.h +++ b/drivers/media/dvb/frontends/cx24110.h | |||
@@ -31,11 +31,6 @@ struct cx24110_config | |||
31 | { | 31 | { |
32 | /* the demodulator's i2c address */ | 32 | /* the demodulator's i2c address */ |
33 | u8 demod_address; | 33 | u8 demod_address; |
34 | |||
35 | /* PLL maintenance */ | ||
36 | int (*pll_init)(struct dvb_frontend* fe); | ||
37 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
38 | int (*pll_sleep)(struct dvb_frontend* fe); | ||
39 | }; | 34 | }; |
40 | 35 | ||
41 | extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, | 36 | extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, |
diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb/frontends/cx24123.c index 691dc840dcc0..f2f795cba56a 100644 --- a/drivers/media/dvb/frontends/cx24123.c +++ b/drivers/media/dvb/frontends/cx24123.c | |||
@@ -41,14 +41,12 @@ static int debug; | |||
41 | struct cx24123_state | 41 | struct cx24123_state |
42 | { | 42 | { |
43 | struct i2c_adapter* i2c; | 43 | struct i2c_adapter* i2c; |
44 | struct dvb_frontend_ops ops; | ||
45 | const struct cx24123_config* config; | 44 | const struct cx24123_config* config; |
46 | 45 | ||
47 | struct dvb_frontend frontend; | 46 | struct dvb_frontend frontend; |
48 | 47 | ||
49 | u32 lastber; | 48 | u32 lastber; |
50 | u16 snr; | 49 | u16 snr; |
51 | u8 lnbreg; | ||
52 | 50 | ||
53 | /* Some PLL specifics for tuning */ | 51 | /* Some PLL specifics for tuning */ |
54 | u32 VCAarg; | 52 | u32 VCAarg; |
@@ -249,29 +247,6 @@ static int cx24123_writereg(struct cx24123_state* state, int reg, int data) | |||
249 | return 0; | 247 | return 0; |
250 | } | 248 | } |
251 | 249 | ||
252 | static int cx24123_writelnbreg(struct cx24123_state* state, int reg, int data) | ||
253 | { | ||
254 | u8 buf[] = { reg, data }; | ||
255 | /* fixme: put the intersil addr int the config */ | ||
256 | struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = buf, .len = 2 }; | ||
257 | int err; | ||
258 | |||
259 | if (debug>1) | ||
260 | printk("cx24123: %s: writeln addr=0x08, reg 0x%02x, value 0x%02x\n", | ||
261 | __FUNCTION__,reg, data); | ||
262 | |||
263 | if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { | ||
264 | printk("%s: writelnbreg error (err == %i, reg == 0x%02x," | ||
265 | " data == 0x%02x)\n", __FUNCTION__, err, reg, data); | ||
266 | return -EREMOTEIO; | ||
267 | } | ||
268 | |||
269 | /* cache the write, no way to read back */ | ||
270 | state->lnbreg = data; | ||
271 | |||
272 | return 0; | ||
273 | } | ||
274 | |||
275 | static int cx24123_readreg(struct cx24123_state* state, u8 reg) | 250 | static int cx24123_readreg(struct cx24123_state* state, u8 reg) |
276 | { | 251 | { |
277 | int ret; | 252 | int ret; |
@@ -295,11 +270,6 @@ static int cx24123_readreg(struct cx24123_state* state, u8 reg) | |||
295 | return b1[0]; | 270 | return b1[0]; |
296 | } | 271 | } |
297 | 272 | ||
298 | static int cx24123_readlnbreg(struct cx24123_state* state, u8 reg) | ||
299 | { | ||
300 | return state->lnbreg; | ||
301 | } | ||
302 | |||
303 | static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_inversion_t inversion) | 273 | static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_inversion_t inversion) |
304 | { | 274 | { |
305 | u8 nom_reg = cx24123_readreg(state, 0x0e); | 275 | u8 nom_reg = cx24123_readreg(state, 0x0e); |
@@ -458,8 +428,8 @@ static int cx24123_set_symbolrate(struct cx24123_state* state, u32 srate) | |||
458 | u8 pll_mult; | 428 | u8 pll_mult; |
459 | 429 | ||
460 | /* check if symbol rate is within limits */ | 430 | /* check if symbol rate is within limits */ |
461 | if ((srate > state->ops.info.symbol_rate_max) || | 431 | if ((srate > state->frontend.ops.info.symbol_rate_max) || |
462 | (srate < state->ops.info.symbol_rate_min)) | 432 | (srate < state->frontend.ops.info.symbol_rate_min)) |
463 | return -EOPNOTSUPP;; | 433 | return -EOPNOTSUPP;; |
464 | 434 | ||
465 | /* choose the sampling rate high enough for the required operation, | 435 | /* choose the sampling rate high enough for the required operation, |
@@ -687,13 +657,6 @@ static int cx24123_initfe(struct dvb_frontend* fe) | |||
687 | for (i = 0; i < sizeof(cx24123_regdata) / sizeof(cx24123_regdata[0]); i++) | 657 | for (i = 0; i < sizeof(cx24123_regdata) / sizeof(cx24123_regdata[0]); i++) |
688 | cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data); | 658 | cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data); |
689 | 659 | ||
690 | if (state->config->pll_init) | ||
691 | state->config->pll_init(fe); | ||
692 | |||
693 | /* Configure the LNB for 14V */ | ||
694 | if (state->config->use_isl6421) | ||
695 | cx24123_writelnbreg(state, 0x0, 0x2a); | ||
696 | |||
697 | return 0; | 660 | return 0; |
698 | } | 661 | } |
699 | 662 | ||
@@ -702,50 +665,18 @@ static int cx24123_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage | |||
702 | struct cx24123_state *state = fe->demodulator_priv; | 665 | struct cx24123_state *state = fe->demodulator_priv; |
703 | u8 val; | 666 | u8 val; |
704 | 667 | ||
705 | switch (state->config->use_isl6421) { | 668 | val = cx24123_readreg(state, 0x29) & ~0x40; |
706 | |||
707 | case 1: | ||
708 | 669 | ||
709 | val = cx24123_readlnbreg(state, 0x0); | 670 | switch (voltage) { |
710 | 671 | case SEC_VOLTAGE_13: | |
711 | switch (voltage) { | 672 | dprintk("%s: setting voltage 13V\n", __FUNCTION__); |
712 | case SEC_VOLTAGE_13: | 673 | return cx24123_writereg(state, 0x29, val | 0x80); |
713 | dprintk("%s: isl6421 voltage = 13V\n",__FUNCTION__); | 674 | case SEC_VOLTAGE_18: |
714 | return cx24123_writelnbreg(state, 0x0, val & 0x32); /* V 13v */ | 675 | dprintk("%s: setting voltage 18V\n", __FUNCTION__); |
715 | case SEC_VOLTAGE_18: | 676 | return cx24123_writereg(state, 0x29, val & 0x7f); |
716 | dprintk("%s: isl6421 voltage = 18V\n",__FUNCTION__); | 677 | default: |
717 | return cx24123_writelnbreg(state, 0x0, val | 0x04); /* H 18v */ | 678 | return -EINVAL; |
718 | case SEC_VOLTAGE_OFF: | 679 | }; |
719 | dprintk("%s: isl5421 voltage off\n",__FUNCTION__); | ||
720 | return cx24123_writelnbreg(state, 0x0, val & 0x30); | ||
721 | default: | ||
722 | return -EINVAL; | ||
723 | }; | ||
724 | |||
725 | case 0: | ||
726 | |||
727 | val = cx24123_readreg(state, 0x29); | ||
728 | |||
729 | switch (voltage) { | ||
730 | case SEC_VOLTAGE_13: | ||
731 | dprintk("%s: setting voltage 13V\n", __FUNCTION__); | ||
732 | if (state->config->enable_lnb_voltage) | ||
733 | state->config->enable_lnb_voltage(fe, 1); | ||
734 | return cx24123_writereg(state, 0x29, val | 0x80); | ||
735 | case SEC_VOLTAGE_18: | ||
736 | dprintk("%s: setting voltage 18V\n", __FUNCTION__); | ||
737 | if (state->config->enable_lnb_voltage) | ||
738 | state->config->enable_lnb_voltage(fe, 1); | ||
739 | return cx24123_writereg(state, 0x29, val & 0x7f); | ||
740 | case SEC_VOLTAGE_OFF: | ||
741 | dprintk("%s: setting voltage off\n", __FUNCTION__); | ||
742 | if (state->config->enable_lnb_voltage) | ||
743 | state->config->enable_lnb_voltage(fe, 0); | ||
744 | return 0; | ||
745 | default: | ||
746 | return -EINVAL; | ||
747 | }; | ||
748 | } | ||
749 | 680 | ||
750 | return 0; | 681 | return 0; |
751 | } | 682 | } |
@@ -766,27 +697,20 @@ static void cx24123_wait_for_diseqc(struct cx24123_state *state) | |||
766 | static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd) | 697 | static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd) |
767 | { | 698 | { |
768 | struct cx24123_state *state = fe->demodulator_priv; | 699 | struct cx24123_state *state = fe->demodulator_priv; |
769 | int i, val; | 700 | int i, val, tone; |
770 | 701 | ||
771 | dprintk("%s:\n",__FUNCTION__); | 702 | dprintk("%s:\n",__FUNCTION__); |
772 | 703 | ||
773 | /* check if continuous tone has been stopped */ | 704 | /* stop continuous tone if enabled */ |
774 | if (state->config->use_isl6421) | 705 | tone = cx24123_readreg(state, 0x29); |
775 | val = cx24123_readlnbreg(state, 0x00) & 0x10; | 706 | if (tone & 0x10) |
776 | else | 707 | cx24123_writereg(state, 0x29, tone & ~0x50); |
777 | val = cx24123_readreg(state, 0x29) & 0x10; | ||
778 | |||
779 | |||
780 | if (val) { | ||
781 | printk("%s: ERROR: attempt to send diseqc command before tone is off\n", __FUNCTION__); | ||
782 | return -ENOTSUPP; | ||
783 | } | ||
784 | 708 | ||
785 | /* wait for diseqc queue ready */ | 709 | /* wait for diseqc queue ready */ |
786 | cx24123_wait_for_diseqc(state); | 710 | cx24123_wait_for_diseqc(state); |
787 | 711 | ||
788 | /* select tone mode */ | 712 | /* select tone mode */ |
789 | cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xf8); | 713 | cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb); |
790 | 714 | ||
791 | for (i = 0; i < cmd->msg_len; i++) | 715 | for (i = 0; i < cmd->msg_len; i++) |
792 | cx24123_writereg(state, 0x2C + i, cmd->msg[i]); | 716 | cx24123_writereg(state, 0x2C + i, cmd->msg[i]); |
@@ -797,36 +721,33 @@ static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_ma | |||
797 | /* wait for diseqc message to finish sending */ | 721 | /* wait for diseqc message to finish sending */ |
798 | cx24123_wait_for_diseqc(state); | 722 | cx24123_wait_for_diseqc(state); |
799 | 723 | ||
724 | /* restart continuous tone if enabled */ | ||
725 | if (tone & 0x10) { | ||
726 | cx24123_writereg(state, 0x29, tone & ~0x40); | ||
727 | } | ||
728 | |||
800 | return 0; | 729 | return 0; |
801 | } | 730 | } |
802 | 731 | ||
803 | static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) | 732 | static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) |
804 | { | 733 | { |
805 | struct cx24123_state *state = fe->demodulator_priv; | 734 | struct cx24123_state *state = fe->demodulator_priv; |
806 | int val; | 735 | int val, tone; |
807 | 736 | ||
808 | dprintk("%s:\n", __FUNCTION__); | 737 | dprintk("%s:\n", __FUNCTION__); |
809 | 738 | ||
810 | /* check if continuous tone has been stoped */ | 739 | /* stop continuous tone if enabled */ |
811 | if (state->config->use_isl6421) | 740 | tone = cx24123_readreg(state, 0x29); |
812 | val = cx24123_readlnbreg(state, 0x00) & 0x10; | 741 | if (tone & 0x10) |
813 | else | 742 | cx24123_writereg(state, 0x29, tone & ~0x50); |
814 | val = cx24123_readreg(state, 0x29) & 0x10; | ||
815 | |||
816 | |||
817 | if (val) { | ||
818 | printk("%s: ERROR: attempt to send diseqc command before tone is off\n", __FUNCTION__); | ||
819 | return -ENOTSUPP; | ||
820 | } | ||
821 | 743 | ||
744 | /* wait for diseqc queue ready */ | ||
822 | cx24123_wait_for_diseqc(state); | 745 | cx24123_wait_for_diseqc(state); |
823 | 746 | ||
824 | /* select tone mode */ | 747 | /* select tone mode */ |
825 | val = cx24123_readreg(state, 0x2a) & 0xf8; | 748 | cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) | 0x4); |
826 | cx24123_writereg(state, 0x2a, val | 0x04); | 749 | msleep(30); |
827 | |||
828 | val = cx24123_readreg(state, 0x29); | 750 | val = cx24123_readreg(state, 0x29); |
829 | |||
830 | if (burst == SEC_MINI_A) | 751 | if (burst == SEC_MINI_A) |
831 | cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x00)); | 752 | cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x00)); |
832 | else if (burst == SEC_MINI_B) | 753 | else if (burst == SEC_MINI_B) |
@@ -835,7 +756,12 @@ static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t | |||
835 | return -EINVAL; | 756 | return -EINVAL; |
836 | 757 | ||
837 | cx24123_wait_for_diseqc(state); | 758 | cx24123_wait_for_diseqc(state); |
759 | cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb); | ||
838 | 760 | ||
761 | /* restart continuous tone if enabled */ | ||
762 | if (tone & 0x10) { | ||
763 | cx24123_writereg(state, 0x29, tone & ~0x40); | ||
764 | } | ||
839 | return 0; | 765 | return 0; |
840 | } | 766 | } |
841 | 767 | ||
@@ -976,38 +902,21 @@ static int cx24123_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | |||
976 | struct cx24123_state *state = fe->demodulator_priv; | 902 | struct cx24123_state *state = fe->demodulator_priv; |
977 | u8 val; | 903 | u8 val; |
978 | 904 | ||
979 | switch (state->config->use_isl6421) { | 905 | /* wait for diseqc queue ready */ |
980 | case 1: | 906 | cx24123_wait_for_diseqc(state); |
981 | |||
982 | val = cx24123_readlnbreg(state, 0x0); | ||
983 | |||
984 | switch (tone) { | ||
985 | case SEC_TONE_ON: | ||
986 | dprintk("%s: isl6421 sec tone on\n",__FUNCTION__); | ||
987 | return cx24123_writelnbreg(state, 0x0, val | 0x10); | ||
988 | case SEC_TONE_OFF: | ||
989 | dprintk("%s: isl6421 sec tone off\n",__FUNCTION__); | ||
990 | return cx24123_writelnbreg(state, 0x0, val & 0x2f); | ||
991 | default: | ||
992 | printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone); | ||
993 | return -EINVAL; | ||
994 | } | ||
995 | |||
996 | case 0: | ||
997 | 907 | ||
998 | val = cx24123_readreg(state, 0x29); | 908 | val = cx24123_readreg(state, 0x29) & ~0x40; |
999 | 909 | ||
1000 | switch (tone) { | 910 | switch (tone) { |
1001 | case SEC_TONE_ON: | 911 | case SEC_TONE_ON: |
1002 | dprintk("%s: setting tone on\n", __FUNCTION__); | 912 | dprintk("%s: setting tone on\n", __FUNCTION__); |
1003 | return cx24123_writereg(state, 0x29, val | 0x10); | 913 | return cx24123_writereg(state, 0x29, val | 0x10); |
1004 | case SEC_TONE_OFF: | 914 | case SEC_TONE_OFF: |
1005 | dprintk("%s: setting tone off\n",__FUNCTION__); | 915 | dprintk("%s: setting tone off\n",__FUNCTION__); |
1006 | return cx24123_writereg(state, 0x29, val & 0xef); | 916 | return cx24123_writereg(state, 0x29, val & 0xef); |
1007 | default: | 917 | default: |
1008 | printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone); | 918 | printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone); |
1009 | return -EINVAL; | 919 | return -EINVAL; |
1010 | } | ||
1011 | } | 920 | } |
1012 | 921 | ||
1013 | return 0; | 922 | return 0; |
@@ -1040,10 +949,8 @@ struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, | |||
1040 | /* setup the state */ | 949 | /* setup the state */ |
1041 | state->config = config; | 950 | state->config = config; |
1042 | state->i2c = i2c; | 951 | state->i2c = i2c; |
1043 | memcpy(&state->ops, &cx24123_ops, sizeof(struct dvb_frontend_ops)); | ||
1044 | state->lastber = 0; | 952 | state->lastber = 0; |
1045 | state->snr = 0; | 953 | state->snr = 0; |
1046 | state->lnbreg = 0; | ||
1047 | state->VCAarg = 0; | 954 | state->VCAarg = 0; |
1048 | state->VGAarg = 0; | 955 | state->VGAarg = 0; |
1049 | state->bandselectarg = 0; | 956 | state->bandselectarg = 0; |
@@ -1059,7 +966,7 @@ struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, | |||
1059 | } | 966 | } |
1060 | 967 | ||
1061 | /* create dvb_frontend */ | 968 | /* create dvb_frontend */ |
1062 | state->frontend.ops = &state->ops; | 969 | memcpy(&state->frontend.ops, &cx24123_ops, sizeof(struct dvb_frontend_ops)); |
1063 | state->frontend.demodulator_priv = state; | 970 | state->frontend.demodulator_priv = state; |
1064 | return &state->frontend; | 971 | return &state->frontend; |
1065 | 972 | ||
diff --git a/drivers/media/dvb/frontends/cx24123.h b/drivers/media/dvb/frontends/cx24123.h index 0c922b5e9263..9606f825935c 100644 --- a/drivers/media/dvb/frontends/cx24123.h +++ b/drivers/media/dvb/frontends/cx24123.h | |||
@@ -28,21 +28,8 @@ struct cx24123_config | |||
28 | /* the demodulator's i2c address */ | 28 | /* the demodulator's i2c address */ |
29 | u8 demod_address; | 29 | u8 demod_address; |
30 | 30 | ||
31 | /* | ||
32 | cards like Hauppauge Nova-S Plus/Nova-SE2 use an Intersil ISL6421 chip | ||
33 | for LNB control, while KWorld DVB-S 100 use the LNBDC and LNBTone bits | ||
34 | from register 0x29 of the CX24123 demodulator | ||
35 | */ | ||
36 | int use_isl6421; | ||
37 | |||
38 | /* PLL maintenance */ | ||
39 | int (*pll_init)(struct dvb_frontend* fe); | ||
40 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
41 | |||
42 | /* Need to set device param for start_dma */ | 31 | /* Need to set device param for start_dma */ |
43 | int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); | 32 | int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); |
44 | |||
45 | void (*enable_lnb_voltage)(struct dvb_frontend* fe, int on); | ||
46 | }; | 33 | }; |
47 | 34 | ||
48 | extern struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, | 35 | extern struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, |
diff --git a/drivers/media/dvb/frontends/dib3000-common.h b/drivers/media/dvb/frontends/dib3000-common.h index c31d6df15472..be1c0d3e1389 100644 --- a/drivers/media/dvb/frontends/dib3000-common.h +++ b/drivers/media/dvb/frontends/dib3000-common.h | |||
@@ -38,8 +38,6 @@ | |||
38 | struct dib3000_state { | 38 | struct dib3000_state { |
39 | struct i2c_adapter* i2c; | 39 | struct i2c_adapter* i2c; |
40 | 40 | ||
41 | struct dvb_frontend_ops ops; | ||
42 | |||
43 | /* configuration settings */ | 41 | /* configuration settings */ |
44 | struct dib3000_config config; | 42 | struct dib3000_config config; |
45 | 43 | ||
diff --git a/drivers/media/dvb/frontends/dib3000.h b/drivers/media/dvb/frontends/dib3000.h index 2d5475b5c063..ec927628d273 100644 --- a/drivers/media/dvb/frontends/dib3000.h +++ b/drivers/media/dvb/frontends/dib3000.h | |||
@@ -30,10 +30,6 @@ struct dib3000_config | |||
30 | { | 30 | { |
31 | /* the demodulator's i2c address */ | 31 | /* the demodulator's i2c address */ |
32 | u8 demod_address; | 32 | u8 demod_address; |
33 | |||
34 | /* PLL maintenance and the i2c address of the PLL */ | ||
35 | int (*pll_init)(struct dvb_frontend *fe); | ||
36 | int (*pll_set)(struct dvb_frontend *fe, struct dvb_frontend_parameters* params); | ||
37 | }; | 33 | }; |
38 | 34 | ||
39 | struct dib_fe_xfer_ops | 35 | struct dib_fe_xfer_ops |
diff --git a/drivers/media/dvb/frontends/dib3000mb.c b/drivers/media/dvb/frontends/dib3000mb.c index ae589adb1c0a..7c6dc7e30900 100644 --- a/drivers/media/dvb/frontends/dib3000mb.c +++ b/drivers/media/dvb/frontends/dib3000mb.c | |||
@@ -60,8 +60,9 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe, | |||
60 | fe_code_rate_t fe_cr = FEC_NONE; | 60 | fe_code_rate_t fe_cr = FEC_NONE; |
61 | int search_state, seq; | 61 | int search_state, seq; |
62 | 62 | ||
63 | if (tuner && state->config.pll_set) { | 63 | if (tuner && fe->ops.tuner_ops.set_params) { |
64 | state->config.pll_set(fe, fep); | 64 | fe->ops.tuner_ops.set_params(fe, fep); |
65 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); | ||
65 | 66 | ||
66 | deb_setf("bandwidth: "); | 67 | deb_setf("bandwidth: "); |
67 | switch (ofdm->bandwidth) { | 68 | switch (ofdm->bandwidth) { |
@@ -386,9 +387,6 @@ static int dib3000mb_fe_init(struct dvb_frontend* fe, int mobile_mode) | |||
386 | 387 | ||
387 | wr(DIB3000MB_REG_DATA_IN_DIVERSITY, DIB3000MB_DATA_DIVERSITY_IN_OFF); | 388 | wr(DIB3000MB_REG_DATA_IN_DIVERSITY, DIB3000MB_DATA_DIVERSITY_IN_OFF); |
388 | 389 | ||
389 | if (state->config.pll_init) | ||
390 | state->config.pll_init(fe); | ||
391 | |||
392 | return 0; | 390 | return 0; |
393 | } | 391 | } |
394 | 392 | ||
@@ -707,7 +705,6 @@ struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config, | |||
707 | /* setup the state */ | 705 | /* setup the state */ |
708 | state->i2c = i2c; | 706 | state->i2c = i2c; |
709 | memcpy(&state->config,config,sizeof(struct dib3000_config)); | 707 | memcpy(&state->config,config,sizeof(struct dib3000_config)); |
710 | memcpy(&state->ops, &dib3000mb_ops, sizeof(struct dvb_frontend_ops)); | ||
711 | 708 | ||
712 | /* check for the correct demod */ | 709 | /* check for the correct demod */ |
713 | if (rd(DIB3000_REG_MANUFACTOR_ID) != DIB3000_I2C_ID_DIBCOM) | 710 | if (rd(DIB3000_REG_MANUFACTOR_ID) != DIB3000_I2C_ID_DIBCOM) |
@@ -717,7 +714,7 @@ struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config, | |||
717 | goto error; | 714 | goto error; |
718 | 715 | ||
719 | /* create dvb_frontend */ | 716 | /* create dvb_frontend */ |
720 | state->frontend.ops = &state->ops; | 717 | memcpy(&state->frontend.ops, &dib3000mb_ops, sizeof(struct dvb_frontend_ops)); |
721 | state->frontend.demodulator_priv = state; | 718 | state->frontend.demodulator_priv = state; |
722 | 719 | ||
723 | /* set the xfer operations */ | 720 | /* set the xfer operations */ |
diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c index 3b303dbb6156..6c3be2529980 100644 --- a/drivers/media/dvb/frontends/dib3000mc.c +++ b/drivers/media/dvb/frontends/dib3000mc.c | |||
@@ -462,8 +462,9 @@ static int dib3000mc_set_frontend(struct dvb_frontend* fe, | |||
462 | int search_state,auto_val; | 462 | int search_state,auto_val; |
463 | u16 val; | 463 | u16 val; |
464 | 464 | ||
465 | if (tuner && state->config.pll_set) { /* initial call from dvb */ | 465 | if (tuner && fe->ops.tuner_ops.set_params) { /* initial call from dvb */ |
466 | state->config.pll_set(fe,fep); | 466 | fe->ops.tuner_ops.set_params(fe, fep); |
467 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); | ||
467 | 468 | ||
468 | state->last_tuned_freq = fep->frequency; | 469 | state->last_tuned_freq = fep->frequency; |
469 | // if (!scanboost) { | 470 | // if (!scanboost) { |
@@ -642,9 +643,6 @@ static int dib3000mc_fe_init(struct dvb_frontend* fe, int mobile_mode) | |||
642 | 643 | ||
643 | set_or(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_DIV_IN_OFF); | 644 | set_or(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_DIV_IN_OFF); |
644 | 645 | ||
645 | if (state->config.pll_init) | ||
646 | state->config.pll_init(fe); | ||
647 | |||
648 | deb_info("init end\n"); | 646 | deb_info("init end\n"); |
649 | return 0; | 647 | return 0; |
650 | } | 648 | } |
@@ -839,7 +837,6 @@ struct dvb_frontend* dib3000mc_attach(const struct dib3000_config* config, | |||
839 | /* setup the state */ | 837 | /* setup the state */ |
840 | state->i2c = i2c; | 838 | state->i2c = i2c; |
841 | memcpy(&state->config,config,sizeof(struct dib3000_config)); | 839 | memcpy(&state->config,config,sizeof(struct dib3000_config)); |
842 | memcpy(&state->ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops)); | ||
843 | 840 | ||
844 | /* check for the correct demod */ | 841 | /* check for the correct demod */ |
845 | if (rd(DIB3000_REG_MANUFACTOR_ID) != DIB3000_I2C_ID_DIBCOM) | 842 | if (rd(DIB3000_REG_MANUFACTOR_ID) != DIB3000_I2C_ID_DIBCOM) |
@@ -859,7 +856,7 @@ struct dvb_frontend* dib3000mc_attach(const struct dib3000_config* config, | |||
859 | } | 856 | } |
860 | 857 | ||
861 | /* create dvb_frontend */ | 858 | /* create dvb_frontend */ |
862 | state->frontend.ops = &state->ops; | 859 | memcpy(&state->frontend.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops)); |
863 | state->frontend.demodulator_priv = state; | 860 | state->frontend.demodulator_priv = state; |
864 | 861 | ||
865 | /* set the xfer operations */ | 862 | /* set the xfer operations */ |
@@ -876,6 +873,7 @@ error: | |||
876 | kfree(state); | 873 | kfree(state); |
877 | return NULL; | 874 | return NULL; |
878 | } | 875 | } |
876 | EXPORT_SYMBOL(dib3000mc_attach); | ||
879 | 877 | ||
880 | static struct dvb_frontend_ops dib3000mc_ops = { | 878 | static struct dvb_frontend_ops dib3000mc_ops = { |
881 | 879 | ||
@@ -914,5 +912,3 @@ static struct dvb_frontend_ops dib3000mc_ops = { | |||
914 | MODULE_AUTHOR(DRIVER_AUTHOR); | 912 | MODULE_AUTHOR(DRIVER_AUTHOR); |
915 | MODULE_DESCRIPTION(DRIVER_DESC); | 913 | MODULE_DESCRIPTION(DRIVER_DESC); |
916 | MODULE_LICENSE("GPL"); | 914 | MODULE_LICENSE("GPL"); |
917 | |||
918 | EXPORT_SYMBOL(dib3000mc_attach); | ||
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c index 791706ec1da3..a189683454b7 100644 --- a/drivers/media/dvb/frontends/dvb-pll.c +++ b/drivers/media/dvb/frontends/dvb-pll.c | |||
@@ -227,10 +227,10 @@ struct dvb_pll_desc dvb_pll_tua6034 = { | |||
227 | EXPORT_SYMBOL(dvb_pll_tua6034); | 227 | EXPORT_SYMBOL(dvb_pll_tua6034); |
228 | 228 | ||
229 | /* Infineon TUA6034 | 229 | /* Infineon TUA6034 |
230 | * used in LG TDVS H061F and LG TDVS H062F | 230 | * used in LG TDVS-H061F, LG TDVS-H062F and LG TDVS-H064F |
231 | */ | 231 | */ |
232 | struct dvb_pll_desc dvb_pll_tdvs_tua6034 = { | 232 | struct dvb_pll_desc dvb_pll_lg_tdvs_h06xf = { |
233 | .name = "LG/Infineon TUA6034", | 233 | .name = "LG TDVS-H06xF", |
234 | .min = 54000000, | 234 | .min = 54000000, |
235 | .max = 863000000, | 235 | .max = 863000000, |
236 | .count = 3, | 236 | .count = 3, |
@@ -240,7 +240,7 @@ struct dvb_pll_desc dvb_pll_tdvs_tua6034 = { | |||
240 | { 999999999, 44000000, 62500, 0xce, 0x04 }, | 240 | { 999999999, 44000000, 62500, 0xce, 0x04 }, |
241 | }, | 241 | }, |
242 | }; | 242 | }; |
243 | EXPORT_SYMBOL(dvb_pll_tdvs_tua6034); | 243 | EXPORT_SYMBOL(dvb_pll_lg_tdvs_h06xf); |
244 | 244 | ||
245 | /* Philips FMD1216ME | 245 | /* Philips FMD1216ME |
246 | * used in Medion Hybrid PCMCIA card and USB Box | 246 | * used in Medion Hybrid PCMCIA card and USB Box |
@@ -419,6 +419,19 @@ struct dvb_pll_desc dvb_pll_thomson_fe6600 = { | |||
419 | }; | 419 | }; |
420 | EXPORT_SYMBOL(dvb_pll_thomson_fe6600); | 420 | EXPORT_SYMBOL(dvb_pll_thomson_fe6600); |
421 | 421 | ||
422 | struct dvb_pll_priv { | ||
423 | /* i2c details */ | ||
424 | int pll_i2c_address; | ||
425 | struct i2c_adapter *i2c; | ||
426 | |||
427 | /* the PLL descriptor */ | ||
428 | struct dvb_pll_desc *pll_desc; | ||
429 | |||
430 | /* cached frequency/bandwidth */ | ||
431 | u32 frequency; | ||
432 | u32 bandwidth; | ||
433 | }; | ||
434 | |||
422 | /* ----------------------------------------------------------- */ | 435 | /* ----------------------------------------------------------- */ |
423 | /* code */ | 436 | /* code */ |
424 | 437 | ||
@@ -443,7 +456,8 @@ int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, | |||
443 | if (debug) | 456 | if (debug) |
444 | printk("pll: %s: freq=%d bw=%d | i=%d/%d\n", | 457 | printk("pll: %s: freq=%d bw=%d | i=%d/%d\n", |
445 | desc->name, freq, bandwidth, i, desc->count); | 458 | desc->name, freq, bandwidth, i, desc->count); |
446 | BUG_ON(i == desc->count); | 459 | if (i == desc->count) |
460 | return -EINVAL; | ||
447 | 461 | ||
448 | div = (freq + desc->entries[i].offset) / desc->entries[i].stepsize; | 462 | div = (freq + desc->entries[i].offset) / desc->entries[i].stepsize; |
449 | buf[0] = div >> 8; | 463 | buf[0] = div >> 8; |
@@ -462,6 +476,163 @@ int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, | |||
462 | } | 476 | } |
463 | EXPORT_SYMBOL(dvb_pll_configure); | 477 | EXPORT_SYMBOL(dvb_pll_configure); |
464 | 478 | ||
479 | static int dvb_pll_release(struct dvb_frontend *fe) | ||
480 | { | ||
481 | if (fe->tuner_priv) | ||
482 | kfree(fe->tuner_priv); | ||
483 | fe->tuner_priv = NULL; | ||
484 | return 0; | ||
485 | } | ||
486 | |||
487 | static int dvb_pll_sleep(struct dvb_frontend *fe) | ||
488 | { | ||
489 | struct dvb_pll_priv *priv = fe->tuner_priv; | ||
490 | u8 buf[4]; | ||
491 | struct i2c_msg msg = | ||
492 | { .addr = priv->pll_i2c_address, .flags = 0, .buf = buf, .len = sizeof(buf) }; | ||
493 | int i; | ||
494 | int result; | ||
495 | |||
496 | for (i = 0; i < priv->pll_desc->count; i++) { | ||
497 | if (priv->pll_desc->entries[i].limit == 0) | ||
498 | break; | ||
499 | } | ||
500 | if (i == priv->pll_desc->count) | ||
501 | return 0; | ||
502 | |||
503 | buf[0] = 0; | ||
504 | buf[1] = 0; | ||
505 | buf[2] = priv->pll_desc->entries[i].config; | ||
506 | buf[3] = priv->pll_desc->entries[i].cb; | ||
507 | |||
508 | if (fe->ops.i2c_gate_ctrl) | ||
509 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
510 | if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) { | ||
511 | return result; | ||
512 | } | ||
513 | |||
514 | return 0; | ||
515 | } | ||
516 | |||
517 | static int dvb_pll_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | ||
518 | { | ||
519 | struct dvb_pll_priv *priv = fe->tuner_priv; | ||
520 | u8 buf[4]; | ||
521 | struct i2c_msg msg = | ||
522 | { .addr = priv->pll_i2c_address, .flags = 0, .buf = buf, .len = sizeof(buf) }; | ||
523 | int result; | ||
524 | u32 div; | ||
525 | int i; | ||
526 | u32 bandwidth = 0; | ||
527 | |||
528 | if (priv->i2c == NULL) | ||
529 | return -EINVAL; | ||
530 | |||
531 | // DVBT bandwidth only just now | ||
532 | if (fe->ops.info.type == FE_OFDM) { | ||
533 | bandwidth = params->u.ofdm.bandwidth; | ||
534 | } | ||
535 | |||
536 | if ((result = dvb_pll_configure(priv->pll_desc, buf, params->frequency, bandwidth)) != 0) | ||
537 | return result; | ||
538 | |||
539 | if (fe->ops.i2c_gate_ctrl) | ||
540 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
541 | if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) { | ||
542 | return result; | ||
543 | } | ||
544 | |||
545 | // calculate the frequency we set it to | ||
546 | for (i = 0; i < priv->pll_desc->count; i++) { | ||
547 | if (params->frequency > priv->pll_desc->entries[i].limit) | ||
548 | continue; | ||
549 | break; | ||
550 | } | ||
551 | div = (params->frequency + priv->pll_desc->entries[i].offset) / priv->pll_desc->entries[i].stepsize; | ||
552 | priv->frequency = (div * priv->pll_desc->entries[i].stepsize) - priv->pll_desc->entries[i].offset; | ||
553 | priv->bandwidth = bandwidth; | ||
554 | |||
555 | return 0; | ||
556 | } | ||
557 | |||
558 | static int dvb_pll_calc_regs(struct dvb_frontend *fe, struct dvb_frontend_parameters *params, u8 *buf, int buf_len) | ||
559 | { | ||
560 | struct dvb_pll_priv *priv = fe->tuner_priv; | ||
561 | int result; | ||
562 | u32 div; | ||
563 | int i; | ||
564 | u32 bandwidth = 0; | ||
565 | |||
566 | if (buf_len < 5) | ||
567 | return -EINVAL; | ||
568 | |||
569 | // DVBT bandwidth only just now | ||
570 | if (fe->ops.info.type == FE_OFDM) { | ||
571 | bandwidth = params->u.ofdm.bandwidth; | ||
572 | } | ||
573 | |||
574 | if ((result = dvb_pll_configure(priv->pll_desc, buf+1, params->frequency, bandwidth)) != 0) | ||
575 | return result; | ||
576 | buf[0] = priv->pll_i2c_address; | ||
577 | |||
578 | // calculate the frequency we set it to | ||
579 | for (i = 0; i < priv->pll_desc->count; i++) { | ||
580 | if (params->frequency > priv->pll_desc->entries[i].limit) | ||
581 | continue; | ||
582 | break; | ||
583 | } | ||
584 | div = (params->frequency + priv->pll_desc->entries[i].offset) / priv->pll_desc->entries[i].stepsize; | ||
585 | priv->frequency = (div * priv->pll_desc->entries[i].stepsize) - priv->pll_desc->entries[i].offset; | ||
586 | priv->bandwidth = bandwidth; | ||
587 | |||
588 | return 5; | ||
589 | } | ||
590 | |||
591 | static int dvb_pll_get_frequency(struct dvb_frontend *fe, u32 *frequency) | ||
592 | { | ||
593 | struct dvb_pll_priv *priv = fe->tuner_priv; | ||
594 | *frequency = priv->frequency; | ||
595 | return 0; | ||
596 | } | ||
597 | |||
598 | static int dvb_pll_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) | ||
599 | { | ||
600 | struct dvb_pll_priv *priv = fe->tuner_priv; | ||
601 | *bandwidth = priv->bandwidth; | ||
602 | return 0; | ||
603 | } | ||
604 | |||
605 | static struct dvb_tuner_ops dvb_pll_tuner_ops = { | ||
606 | .release = dvb_pll_release, | ||
607 | .sleep = dvb_pll_sleep, | ||
608 | .set_params = dvb_pll_set_params, | ||
609 | .calc_regs = dvb_pll_calc_regs, | ||
610 | .get_frequency = dvb_pll_get_frequency, | ||
611 | .get_bandwidth = dvb_pll_get_bandwidth, | ||
612 | }; | ||
613 | |||
614 | int dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, struct i2c_adapter *i2c, struct dvb_pll_desc *desc) | ||
615 | { | ||
616 | struct dvb_pll_priv *priv = NULL; | ||
617 | |||
618 | priv = kzalloc(sizeof(struct dvb_pll_priv), GFP_KERNEL); | ||
619 | if (priv == NULL) | ||
620 | return -ENOMEM; | ||
621 | |||
622 | priv->pll_i2c_address = pll_addr; | ||
623 | priv->i2c = i2c; | ||
624 | priv->pll_desc = desc; | ||
625 | |||
626 | memcpy(&fe->ops.tuner_ops, &dvb_pll_tuner_ops, sizeof(struct dvb_tuner_ops)); | ||
627 | strncpy(fe->ops.tuner_ops.info.name, desc->name, 128); | ||
628 | fe->ops.tuner_ops.info.frequency_min = desc->min; | ||
629 | fe->ops.tuner_ops.info.frequency_min = desc->max; | ||
630 | |||
631 | fe->tuner_priv = priv; | ||
632 | return 0; | ||
633 | } | ||
634 | EXPORT_SYMBOL(dvb_pll_attach); | ||
635 | |||
465 | MODULE_DESCRIPTION("dvb pll library"); | 636 | MODULE_DESCRIPTION("dvb pll library"); |
466 | MODULE_AUTHOR("Gerd Knorr"); | 637 | MODULE_AUTHOR("Gerd Knorr"); |
467 | MODULE_LICENSE("GPL"); | 638 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h index 2b8461784989..66361cd18807 100644 --- a/drivers/media/dvb/frontends/dvb-pll.h +++ b/drivers/media/dvb/frontends/dvb-pll.h | |||
@@ -5,6 +5,9 @@ | |||
5 | #ifndef __DVB_PLL_H__ | 5 | #ifndef __DVB_PLL_H__ |
6 | #define __DVB_PLL_H__ | 6 | #define __DVB_PLL_H__ |
7 | 7 | ||
8 | #include <linux/i2c.h> | ||
9 | #include "dvb_frontend.h" | ||
10 | |||
8 | struct dvb_pll_desc { | 11 | struct dvb_pll_desc { |
9 | char *name; | 12 | char *name; |
10 | u32 min; | 13 | u32 min; |
@@ -31,7 +34,7 @@ extern struct dvb_pll_desc dvb_pll_unknown_1; | |||
31 | extern struct dvb_pll_desc dvb_pll_tua6010xs; | 34 | extern struct dvb_pll_desc dvb_pll_tua6010xs; |
32 | extern struct dvb_pll_desc dvb_pll_env57h1xd5; | 35 | extern struct dvb_pll_desc dvb_pll_env57h1xd5; |
33 | extern struct dvb_pll_desc dvb_pll_tua6034; | 36 | extern struct dvb_pll_desc dvb_pll_tua6034; |
34 | extern struct dvb_pll_desc dvb_pll_tdvs_tua6034; | 37 | extern struct dvb_pll_desc dvb_pll_lg_tdvs_h06xf; |
35 | extern struct dvb_pll_desc dvb_pll_tda665x; | 38 | extern struct dvb_pll_desc dvb_pll_tda665x; |
36 | extern struct dvb_pll_desc dvb_pll_fmd1216me; | 39 | extern struct dvb_pll_desc dvb_pll_fmd1216me; |
37 | extern struct dvb_pll_desc dvb_pll_tded4; | 40 | extern struct dvb_pll_desc dvb_pll_tded4; |
@@ -44,7 +47,18 @@ extern struct dvb_pll_desc dvb_pll_philips_td1316; | |||
44 | 47 | ||
45 | extern struct dvb_pll_desc dvb_pll_thomson_fe6600; | 48 | extern struct dvb_pll_desc dvb_pll_thomson_fe6600; |
46 | 49 | ||
47 | int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, | 50 | extern int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, |
48 | u32 freq, int bandwidth); | 51 | u32 freq, int bandwidth); |
49 | 52 | ||
53 | /** | ||
54 | * Attach a dvb-pll to the supplied frontend structure. | ||
55 | * | ||
56 | * @param fe Frontend to attach to. | ||
57 | * @param pll_addr i2c address of the PLL (if used). | ||
58 | * @param i2c i2c adapter to use (set to NULL if not used). | ||
59 | * @param desc dvb_pll_desc to use. | ||
60 | * @return 0 on success, nonzero on failure. | ||
61 | */ | ||
62 | extern int dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, struct i2c_adapter *i2c, struct dvb_pll_desc *desc); | ||
63 | |||
50 | #endif | 64 | #endif |
diff --git a/drivers/media/dvb/frontends/dvb_dummy_fe.c b/drivers/media/dvb/frontends/dvb_dummy_fe.c index 645946a992d9..6271b1e7f6ab 100644 --- a/drivers/media/dvb/frontends/dvb_dummy_fe.c +++ b/drivers/media/dvb/frontends/dvb_dummy_fe.c | |||
@@ -30,7 +30,6 @@ | |||
30 | 30 | ||
31 | 31 | ||
32 | struct dvb_dummy_fe_state { | 32 | struct dvb_dummy_fe_state { |
33 | struct dvb_frontend_ops ops; | ||
34 | struct dvb_frontend frontend; | 33 | struct dvb_frontend frontend; |
35 | }; | 34 | }; |
36 | 35 | ||
@@ -77,6 +76,11 @@ static int dvb_dummy_fe_get_frontend(struct dvb_frontend* fe, struct dvb_fronten | |||
77 | 76 | ||
78 | static int dvb_dummy_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | 77 | static int dvb_dummy_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) |
79 | { | 78 | { |
79 | if (fe->ops->tuner_ops->set_params) { | ||
80 | fe->ops->tuner_ops->set_params(fe, p); | ||
81 | if (fe->ops->i2c_gate_ctrl) fe->ops->i2c_gate_ctrl(fe, 0); | ||
82 | } | ||
83 | |||
80 | return 0; | 84 | return 0; |
81 | } | 85 | } |
82 | 86 | ||
@@ -116,11 +120,8 @@ struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void) | |||
116 | state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL); | 120 | state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL); |
117 | if (state == NULL) goto error; | 121 | if (state == NULL) goto error; |
118 | 122 | ||
119 | /* setup the state */ | ||
120 | memcpy(&state->ops, &dvb_dummy_fe_ofdm_ops, sizeof(struct dvb_frontend_ops)); | ||
121 | |||
122 | /* create dvb_frontend */ | 123 | /* create dvb_frontend */ |
123 | state->frontend.ops = &state->ops; | 124 | memcpy(&state->frontend.ops, &dvb_dummy_fe_ofdm_ops, sizeof(struct dvb_frontend_ops)); |
124 | state->frontend.demodulator_priv = state; | 125 | state->frontend.demodulator_priv = state; |
125 | return &state->frontend; | 126 | return &state->frontend; |
126 | 127 | ||
@@ -139,11 +140,8 @@ struct dvb_frontend* dvb_dummy_fe_qpsk_attach() | |||
139 | state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL); | 140 | state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL); |
140 | if (state == NULL) goto error; | 141 | if (state == NULL) goto error; |
141 | 142 | ||
142 | /* setup the state */ | ||
143 | memcpy(&state->ops, &dvb_dummy_fe_qpsk_ops, sizeof(struct dvb_frontend_ops)); | ||
144 | |||
145 | /* create dvb_frontend */ | 143 | /* create dvb_frontend */ |
146 | state->frontend.ops = &state->ops; | 144 | memcpy(&state->frontend.ops, &dvb_dummy_fe_qpsk_ops, sizeof(struct dvb_frontend_ops)); |
147 | state->frontend.demodulator_priv = state; | 145 | state->frontend.demodulator_priv = state; |
148 | return &state->frontend; | 146 | return &state->frontend; |
149 | 147 | ||
@@ -162,11 +160,8 @@ struct dvb_frontend* dvb_dummy_fe_qam_attach() | |||
162 | state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL); | 160 | state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL); |
163 | if (state == NULL) goto error; | 161 | if (state == NULL) goto error; |
164 | 162 | ||
165 | /* setup the state */ | ||
166 | memcpy(&state->ops, &dvb_dummy_fe_qam_ops, sizeof(struct dvb_frontend_ops)); | ||
167 | |||
168 | /* create dvb_frontend */ | 163 | /* create dvb_frontend */ |
169 | state->frontend.ops = &state->ops; | 164 | memcpy(&state->frontend.ops, &dvb_dummy_fe_qam_ops, sizeof(struct dvb_frontend_ops)); |
170 | state->frontend.demodulator_priv = state; | 165 | state->frontend.demodulator_priv = state; |
171 | return &state->frontend; | 166 | return &state->frontend; |
172 | 167 | ||
diff --git a/drivers/media/dvb/frontends/isl6421.c b/drivers/media/dvb/frontends/isl6421.c new file mode 100644 index 000000000000..58c34db31071 --- /dev/null +++ b/drivers/media/dvb/frontends/isl6421.c | |||
@@ -0,0 +1,149 @@ | |||
1 | /* | ||
2 | * isl6421.h - driver for lnb supply and control ic ISL6421 | ||
3 | * | ||
4 | * Copyright (C) 2006 Andrew de Quincey | ||
5 | * Copyright (C) 2006 Oliver Endriss | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * as published by the Free Software Foundation; either version 2 | ||
10 | * of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
22 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||
23 | * | ||
24 | * | ||
25 | * the project's page is at http://www.linuxtv.org | ||
26 | */ | ||
27 | #include <linux/delay.h> | ||
28 | #include <linux/errno.h> | ||
29 | #include <linux/init.h> | ||
30 | #include <linux/kernel.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/moduleparam.h> | ||
33 | #include <linux/string.h> | ||
34 | #include <linux/slab.h> | ||
35 | |||
36 | #include "dvb_frontend.h" | ||
37 | #include "isl6421.h" | ||
38 | |||
39 | struct isl6421 { | ||
40 | u8 config; | ||
41 | u8 override_or; | ||
42 | u8 override_and; | ||
43 | struct i2c_adapter *i2c; | ||
44 | u8 i2c_addr; | ||
45 | void (*release_chain)(struct dvb_frontend* fe); | ||
46 | }; | ||
47 | |||
48 | static int isl6421_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | ||
49 | { | ||
50 | struct isl6421 *isl6421 = (struct isl6421 *) fe->misc_priv; | ||
51 | struct i2c_msg msg = { .addr = isl6421->i2c_addr, .flags = 0, | ||
52 | .buf = &isl6421->config, | ||
53 | .len = sizeof(isl6421->config) }; | ||
54 | |||
55 | isl6421->config &= ~(ISL6421_VSEL1 | ISL6421_EN1); | ||
56 | |||
57 | switch(voltage) { | ||
58 | case SEC_VOLTAGE_OFF: | ||
59 | break; | ||
60 | case SEC_VOLTAGE_13: | ||
61 | isl6421->config |= ISL6421_EN1; | ||
62 | break; | ||
63 | case SEC_VOLTAGE_18: | ||
64 | isl6421->config |= (ISL6421_EN1 | ISL6421_VSEL1); | ||
65 | break; | ||
66 | default: | ||
67 | return -EINVAL; | ||
68 | }; | ||
69 | |||
70 | isl6421->config |= isl6421->override_or; | ||
71 | isl6421->config &= isl6421->override_and; | ||
72 | |||
73 | return (i2c_transfer(isl6421->i2c, &msg, 1) == 1) ? 0 : -EIO; | ||
74 | } | ||
75 | |||
76 | static int isl6421_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg) | ||
77 | { | ||
78 | struct isl6421 *isl6421 = (struct isl6421 *) fe->misc_priv; | ||
79 | struct i2c_msg msg = { .addr = isl6421->i2c_addr, .flags = 0, | ||
80 | .buf = &isl6421->config, | ||
81 | .len = sizeof(isl6421->config) }; | ||
82 | |||
83 | if (arg) | ||
84 | isl6421->config |= ISL6421_LLC1; | ||
85 | else | ||
86 | isl6421->config &= ~ISL6421_LLC1; | ||
87 | |||
88 | isl6421->config |= isl6421->override_or; | ||
89 | isl6421->config &= isl6421->override_and; | ||
90 | |||
91 | return (i2c_transfer(isl6421->i2c, &msg, 1) == 1) ? 0 : -EIO; | ||
92 | } | ||
93 | |||
94 | static void isl6421_release(struct dvb_frontend *fe) | ||
95 | { | ||
96 | struct isl6421 *isl6421 = (struct isl6421 *) fe->misc_priv; | ||
97 | |||
98 | /* power off */ | ||
99 | isl6421_set_voltage(fe, SEC_VOLTAGE_OFF); | ||
100 | |||
101 | /* free data & call next release routine */ | ||
102 | fe->ops.release = isl6421->release_chain; | ||
103 | kfree(fe->misc_priv); | ||
104 | fe->misc_priv = NULL; | ||
105 | if (fe->ops.release) | ||
106 | fe->ops.release(fe); | ||
107 | } | ||
108 | |||
109 | int isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr, | ||
110 | u8 override_set, u8 override_clear) | ||
111 | { | ||
112 | struct isl6421 *isl6421 = kmalloc(sizeof(struct isl6421), GFP_KERNEL); | ||
113 | if (!isl6421) | ||
114 | return -ENOMEM; | ||
115 | |||
116 | /* default configuration */ | ||
117 | isl6421->config = ISL6421_ISEL1; | ||
118 | isl6421->i2c = i2c; | ||
119 | isl6421->i2c_addr = i2c_addr; | ||
120 | fe->misc_priv = isl6421; | ||
121 | |||
122 | /* bits which should be forced to '1' */ | ||
123 | isl6421->override_or = override_set; | ||
124 | |||
125 | /* bits which should be forced to '0' */ | ||
126 | isl6421->override_and = ~override_clear; | ||
127 | |||
128 | /* detect if it is present or not */ | ||
129 | if (isl6421_set_voltage(fe, SEC_VOLTAGE_OFF)) { | ||
130 | kfree(isl6421); | ||
131 | fe->misc_priv = NULL; | ||
132 | return -EIO; | ||
133 | } | ||
134 | |||
135 | /* install release callback */ | ||
136 | isl6421->release_chain = fe->ops.release; | ||
137 | fe->ops.release = isl6421_release; | ||
138 | |||
139 | /* override frontend ops */ | ||
140 | fe->ops.set_voltage = isl6421_set_voltage; | ||
141 | fe->ops.enable_high_lnb_voltage = isl6421_enable_high_lnb_voltage; | ||
142 | |||
143 | return 0; | ||
144 | } | ||
145 | EXPORT_SYMBOL(isl6421_attach); | ||
146 | |||
147 | MODULE_DESCRIPTION("Driver for lnb supply and control ic isl6421"); | ||
148 | MODULE_AUTHOR("Andrew de Quincey & Oliver Endriss"); | ||
149 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/frontends/isl6421.h b/drivers/media/dvb/frontends/isl6421.h new file mode 100644 index 000000000000..675f80a19b99 --- /dev/null +++ b/drivers/media/dvb/frontends/isl6421.h | |||
@@ -0,0 +1,46 @@ | |||
1 | /* | ||
2 | * isl6421.h - driver for lnb supply and control ic ISL6421 | ||
3 | * | ||
4 | * Copyright (C) 2006 Andrew de Quincey | ||
5 | * Copyright (C) 2006 Oliver Endriss | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * as published by the Free Software Foundation; either version 2 | ||
10 | * of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
22 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||
23 | * | ||
24 | * | ||
25 | * the project's page is at http://www.linuxtv.org | ||
26 | */ | ||
27 | |||
28 | #ifndef _ISL6421_H | ||
29 | #define _ISL6421_H | ||
30 | |||
31 | #include <linux/dvb/frontend.h> | ||
32 | |||
33 | /* system register bits */ | ||
34 | #define ISL6421_OLF1 0x01 | ||
35 | #define ISL6421_EN1 0x02 | ||
36 | #define ISL6421_VSEL1 0x04 | ||
37 | #define ISL6421_LLC1 0x08 | ||
38 | #define ISL6421_ENT1 0x10 | ||
39 | #define ISL6421_ISEL1 0x20 | ||
40 | #define ISL6421_DCL 0x40 | ||
41 | |||
42 | /* override_set and override_clear control which system register bits (above) to always set & clear */ | ||
43 | extern int isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr, | ||
44 | u8 override_set, u8 override_clear); | ||
45 | |||
46 | #endif | ||
diff --git a/drivers/media/dvb/frontends/l64781.c b/drivers/media/dvb/frontends/l64781.c index 1c7c91224472..f3bc82e44a28 100644 --- a/drivers/media/dvb/frontends/l64781.c +++ b/drivers/media/dvb/frontends/l64781.c | |||
@@ -32,7 +32,6 @@ | |||
32 | 32 | ||
33 | struct l64781_state { | 33 | struct l64781_state { |
34 | struct i2c_adapter* i2c; | 34 | struct i2c_adapter* i2c; |
35 | struct dvb_frontend_ops ops; | ||
36 | const struct l64781_config* config; | 35 | const struct l64781_config* config; |
37 | struct dvb_frontend frontend; | 36 | struct dvb_frontend frontend; |
38 | 37 | ||
@@ -141,7 +140,10 @@ static int apply_frontend_param (struct dvb_frontend* fe, struct dvb_frontend_pa | |||
141 | u8 val0x06; | 140 | u8 val0x06; |
142 | int bw = p->bandwidth - BANDWIDTH_8_MHZ; | 141 | int bw = p->bandwidth - BANDWIDTH_8_MHZ; |
143 | 142 | ||
144 | state->config->pll_set(fe, param); | 143 | if (fe->ops.tuner_ops.set_params) { |
144 | fe->ops.tuner_ops.set_params(fe, param); | ||
145 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); | ||
146 | } | ||
145 | 147 | ||
146 | if (param->inversion != INVERSION_ON && | 148 | if (param->inversion != INVERSION_ON && |
147 | param->inversion != INVERSION_OFF) | 149 | param->inversion != INVERSION_OFF) |
@@ -463,8 +465,6 @@ static int l64781_init(struct dvb_frontend* fe) | |||
463 | /* Everything is two's complement, soft bit and CSI_OUT too */ | 465 | /* Everything is two's complement, soft bit and CSI_OUT too */ |
464 | l64781_writereg (state, 0x1e, 0x09); | 466 | l64781_writereg (state, 0x1e, 0x09); |
465 | 467 | ||
466 | if (state->config->pll_init) state->config->pll_init(fe); | ||
467 | |||
468 | /* delay a bit after first init attempt */ | 468 | /* delay a bit after first init attempt */ |
469 | if (state->first) { | 469 | if (state->first) { |
470 | state->first = 0; | 470 | state->first = 0; |
@@ -508,7 +508,6 @@ struct dvb_frontend* l64781_attach(const struct l64781_config* config, | |||
508 | /* setup the state */ | 508 | /* setup the state */ |
509 | state->config = config; | 509 | state->config = config; |
510 | state->i2c = i2c; | 510 | state->i2c = i2c; |
511 | memcpy(&state->ops, &l64781_ops, sizeof(struct dvb_frontend_ops)); | ||
512 | state->first = 1; | 511 | state->first = 1; |
513 | 512 | ||
514 | /** | 513 | /** |
@@ -554,7 +553,7 @@ struct dvb_frontend* l64781_attach(const struct l64781_config* config, | |||
554 | } | 553 | } |
555 | 554 | ||
556 | /* create dvb_frontend */ | 555 | /* create dvb_frontend */ |
557 | state->frontend.ops = &state->ops; | 556 | memcpy(&state->frontend.ops, &l64781_ops, sizeof(struct dvb_frontend_ops)); |
558 | state->frontend.demodulator_priv = state; | 557 | state->frontend.demodulator_priv = state; |
559 | return &state->frontend; | 558 | return &state->frontend; |
560 | 559 | ||
diff --git a/drivers/media/dvb/frontends/l64781.h b/drivers/media/dvb/frontends/l64781.h index 947f65f87465..83b8bc210274 100644 --- a/drivers/media/dvb/frontends/l64781.h +++ b/drivers/media/dvb/frontends/l64781.h | |||
@@ -29,10 +29,6 @@ struct l64781_config | |||
29 | { | 29 | { |
30 | /* the demodulator's i2c address */ | 30 | /* the demodulator's i2c address */ |
31 | u8 demod_address; | 31 | u8 demod_address; |
32 | |||
33 | /* PLL maintenance */ | ||
34 | int (*pll_init)(struct dvb_frontend* fe); | ||
35 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
36 | }; | 32 | }; |
37 | 33 | ||
38 | 34 | ||
diff --git a/drivers/media/dvb/frontends/lg_h06xf.h b/drivers/media/dvb/frontends/lg_h06xf.h new file mode 100644 index 000000000000..754d51d11120 --- /dev/null +++ b/drivers/media/dvb/frontends/lg_h06xf.h | |||
@@ -0,0 +1,64 @@ | |||
1 | /* | ||
2 | * lg_h06xf.h - ATSC Tuner support for LG TDVS-H06xF | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
17 | */ | ||
18 | |||
19 | #ifndef _LG_H06XF_H_ | ||
20 | #define _LG_H06XF_H_ | ||
21 | #include "dvb-pll.h" | ||
22 | |||
23 | static int lg_h06xf_pll_set(struct dvb_frontend* fe, struct i2c_adapter* i2c_adap, | ||
24 | struct dvb_frontend_parameters* params) | ||
25 | { | ||
26 | u8 buf[4]; | ||
27 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, | ||
28 | .buf = buf, .len = sizeof(buf) }; | ||
29 | int err; | ||
30 | |||
31 | dvb_pll_configure(&dvb_pll_lg_tdvs_h06xf, buf, params->frequency, 0); | ||
32 | if (fe->ops.i2c_gate_ctrl) | ||
33 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
34 | if ((err = i2c_transfer(i2c_adap, &msg, 1)) != 1) { | ||
35 | printk(KERN_WARNING "lg_h06xf: %s error " | ||
36 | "(addr %02x <- %02x, err = %i)\n", | ||
37 | __FUNCTION__, buf[0], buf[1], err); | ||
38 | if (err < 0) | ||
39 | return err; | ||
40 | else | ||
41 | return -EREMOTEIO; | ||
42 | } | ||
43 | |||
44 | /* Set the Auxiliary Byte. */ | ||
45 | buf[0] = buf[2]; | ||
46 | buf[0] &= ~0x20; | ||
47 | buf[0] |= 0x18; | ||
48 | buf[1] = 0x50; | ||
49 | msg.len = 2; | ||
50 | if (fe->ops.i2c_gate_ctrl) | ||
51 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
52 | if ((err = i2c_transfer(i2c_adap, &msg, 1)) != 1) { | ||
53 | printk(KERN_WARNING "lg_h06xf: %s error " | ||
54 | "(addr %02x <- %02x, err = %i)\n", | ||
55 | __FUNCTION__, buf[0], buf[1], err); | ||
56 | if (err < 0) | ||
57 | return err; | ||
58 | else | ||
59 | return -EREMOTEIO; | ||
60 | } | ||
61 | |||
62 | return 0; | ||
63 | } | ||
64 | #endif | ||
diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c index 4691ac54bc1d..6e8ad176e1a1 100644 --- a/drivers/media/dvb/frontends/lgdt330x.c +++ b/drivers/media/dvb/frontends/lgdt330x.c | |||
@@ -29,6 +29,7 @@ | |||
29 | * DViCO FusionHDTV 5 Lite | 29 | * DViCO FusionHDTV 5 Lite |
30 | * DViCO FusionHDTV 5 USB Gold | 30 | * DViCO FusionHDTV 5 USB Gold |
31 | * Air2PC/AirStar 2 ATSC 3rd generation (HD5000) | 31 | * Air2PC/AirStar 2 ATSC 3rd generation (HD5000) |
32 | * pcHDTV HD5500 | ||
32 | * | 33 | * |
33 | * TODO: | 34 | * TODO: |
34 | * signal strength always returns 0. | 35 | * signal strength always returns 0. |
@@ -59,7 +60,6 @@ if (debug) printk(KERN_DEBUG "lgdt330x: " args); \ | |||
59 | struct lgdt330x_state | 60 | struct lgdt330x_state |
60 | { | 61 | { |
61 | struct i2c_adapter* i2c; | 62 | struct i2c_adapter* i2c; |
62 | struct dvb_frontend_ops ops; | ||
63 | 63 | ||
64 | /* Configuration settings */ | 64 | /* Configuration settings */ |
65 | const struct lgdt330x_config* config; | 65 | const struct lgdt330x_config* config; |
@@ -399,8 +399,10 @@ static int lgdt330x_set_parameters(struct dvb_frontend* fe, | |||
399 | } | 399 | } |
400 | 400 | ||
401 | /* Tune to the specified frequency */ | 401 | /* Tune to the specified frequency */ |
402 | if (state->config->pll_set) | 402 | if (fe->ops.tuner_ops.set_params) { |
403 | state->config->pll_set(fe, param); | 403 | fe->ops.tuner_ops.set_params(fe, param); |
404 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); | ||
405 | } | ||
404 | 406 | ||
405 | /* Keep track of the new frequency */ | 407 | /* Keep track of the new frequency */ |
406 | /* FIXME this is the wrong way to do this... */ | 408 | /* FIXME this is the wrong way to do this... */ |
@@ -672,6 +674,7 @@ static int lgdt3303_read_snr(struct dvb_frontend* fe, u16* snr) | |||
672 | 674 | ||
673 | if (state->current_modulation == VSB_8) { | 675 | if (state->current_modulation == VSB_8) { |
674 | 676 | ||
677 | i2c_read_demod_bytes(state, 0x6e, buf, 5); | ||
675 | /* Phase Tracker Mean-Square Error Register for VSB */ | 678 | /* Phase Tracker Mean-Square Error Register for VSB */ |
676 | noise = ((buf[0] & 7) << 16) | (buf[3] << 8) | buf[4]; | 679 | noise = ((buf[0] & 7) << 16) | (buf[3] << 8) | buf[4]; |
677 | } else { | 680 | } else { |
@@ -721,16 +724,19 @@ struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config, | |||
721 | /* Setup the state */ | 724 | /* Setup the state */ |
722 | state->config = config; | 725 | state->config = config; |
723 | state->i2c = i2c; | 726 | state->i2c = i2c; |
727 | |||
728 | /* Create dvb_frontend */ | ||
724 | switch (config->demod_chip) { | 729 | switch (config->demod_chip) { |
725 | case LGDT3302: | 730 | case LGDT3302: |
726 | memcpy(&state->ops, &lgdt3302_ops, sizeof(struct dvb_frontend_ops)); | 731 | memcpy(&state->frontend.ops, &lgdt3302_ops, sizeof(struct dvb_frontend_ops)); |
727 | break; | 732 | break; |
728 | case LGDT3303: | 733 | case LGDT3303: |
729 | memcpy(&state->ops, &lgdt3303_ops, sizeof(struct dvb_frontend_ops)); | 734 | memcpy(&state->frontend.ops, &lgdt3303_ops, sizeof(struct dvb_frontend_ops)); |
730 | break; | 735 | break; |
731 | default: | 736 | default: |
732 | goto error; | 737 | goto error; |
733 | } | 738 | } |
739 | state->frontend.demodulator_priv = state; | ||
734 | 740 | ||
735 | /* Verify communication with demod chip */ | 741 | /* Verify communication with demod chip */ |
736 | if (i2c_read_demod_bytes(state, 2, buf, 1)) | 742 | if (i2c_read_demod_bytes(state, 2, buf, 1)) |
@@ -739,9 +745,6 @@ struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config, | |||
739 | state->current_frequency = -1; | 745 | state->current_frequency = -1; |
740 | state->current_modulation = -1; | 746 | state->current_modulation = -1; |
741 | 747 | ||
742 | /* Create dvb_frontend */ | ||
743 | state->frontend.ops = &state->ops; | ||
744 | state->frontend.demodulator_priv = state; | ||
745 | return &state->frontend; | 748 | return &state->frontend; |
746 | 749 | ||
747 | error: | 750 | error: |
diff --git a/drivers/media/dvb/frontends/lgdt330x.h b/drivers/media/dvb/frontends/lgdt330x.h index 2a6529cccf1a..bad903c6f0f8 100644 --- a/drivers/media/dvb/frontends/lgdt330x.h +++ b/drivers/media/dvb/frontends/lgdt330x.h | |||
@@ -43,7 +43,6 @@ struct lgdt330x_config | |||
43 | 43 | ||
44 | /* PLL interface */ | 44 | /* PLL interface */ |
45 | int (*pll_rf_set) (struct dvb_frontend* fe, int index); | 45 | int (*pll_rf_set) (struct dvb_frontend* fe, int index); |
46 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
47 | 46 | ||
48 | /* Need to set device param for start_dma */ | 47 | /* Need to set device param for start_dma */ |
49 | int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); | 48 | int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); |
diff --git a/drivers/media/dvb/frontends/lnbp21.c b/drivers/media/dvb/frontends/lnbp21.c new file mode 100644 index 000000000000..e933edc8dd29 --- /dev/null +++ b/drivers/media/dvb/frontends/lnbp21.c | |||
@@ -0,0 +1,145 @@ | |||
1 | /* | ||
2 | * lnbp21.h - driver for lnb supply and control ic lnbp21 | ||
3 | * | ||
4 | * Copyright (C) 2006 Oliver Endriss | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version 2 | ||
9 | * of the License, or (at your option) any later version. | ||
10 | * | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
21 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||
22 | * | ||
23 | * | ||
24 | * the project's page is at http://www.linuxtv.org | ||
25 | */ | ||
26 | #include <linux/delay.h> | ||
27 | #include <linux/errno.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/module.h> | ||
31 | #include <linux/moduleparam.h> | ||
32 | #include <linux/string.h> | ||
33 | #include <linux/slab.h> | ||
34 | |||
35 | #include "dvb_frontend.h" | ||
36 | #include "lnbp21.h" | ||
37 | |||
38 | struct lnbp21 { | ||
39 | u8 config; | ||
40 | u8 override_or; | ||
41 | u8 override_and; | ||
42 | struct i2c_adapter *i2c; | ||
43 | void (*release_chain)(struct dvb_frontend* fe); | ||
44 | }; | ||
45 | |||
46 | static int lnbp21_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | ||
47 | { | ||
48 | struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv; | ||
49 | struct i2c_msg msg = { .addr = 0x08, .flags = 0, | ||
50 | .buf = &lnbp21->config, | ||
51 | .len = sizeof(lnbp21->config) }; | ||
52 | |||
53 | lnbp21->config &= ~(LNBP21_VSEL | LNBP21_EN); | ||
54 | |||
55 | switch(voltage) { | ||
56 | case SEC_VOLTAGE_OFF: | ||
57 | break; | ||
58 | case SEC_VOLTAGE_13: | ||
59 | lnbp21->config |= LNBP21_EN; | ||
60 | break; | ||
61 | case SEC_VOLTAGE_18: | ||
62 | lnbp21->config |= (LNBP21_EN | LNBP21_VSEL); | ||
63 | break; | ||
64 | default: | ||
65 | return -EINVAL; | ||
66 | }; | ||
67 | |||
68 | lnbp21->config |= lnbp21->override_or; | ||
69 | lnbp21->config &= lnbp21->override_and; | ||
70 | |||
71 | return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO; | ||
72 | } | ||
73 | |||
74 | static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg) | ||
75 | { | ||
76 | struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv; | ||
77 | struct i2c_msg msg = { .addr = 0x08, .flags = 0, | ||
78 | .buf = &lnbp21->config, | ||
79 | .len = sizeof(lnbp21->config) }; | ||
80 | |||
81 | if (arg) | ||
82 | lnbp21->config |= LNBP21_LLC; | ||
83 | else | ||
84 | lnbp21->config &= ~LNBP21_LLC; | ||
85 | |||
86 | lnbp21->config |= lnbp21->override_or; | ||
87 | lnbp21->config &= lnbp21->override_and; | ||
88 | |||
89 | return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO; | ||
90 | } | ||
91 | |||
92 | static void lnbp21_release(struct dvb_frontend *fe) | ||
93 | { | ||
94 | struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv; | ||
95 | |||
96 | /* LNBP power off */ | ||
97 | lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF); | ||
98 | |||
99 | /* free data & call next release routine */ | ||
100 | fe->ops.release = lnbp21->release_chain; | ||
101 | kfree(fe->misc_priv); | ||
102 | fe->misc_priv = NULL; | ||
103 | if (fe->ops.release) | ||
104 | fe->ops.release(fe); | ||
105 | } | ||
106 | |||
107 | int lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear) | ||
108 | { | ||
109 | struct lnbp21 *lnbp21 = kmalloc(sizeof(struct lnbp21), GFP_KERNEL); | ||
110 | if (!lnbp21) | ||
111 | return -ENOMEM; | ||
112 | |||
113 | /* default configuration */ | ||
114 | lnbp21->config = LNBP21_ISEL; | ||
115 | lnbp21->i2c = i2c; | ||
116 | fe->misc_priv = lnbp21; | ||
117 | |||
118 | /* bits which should be forced to '1' */ | ||
119 | lnbp21->override_or = override_set; | ||
120 | |||
121 | /* bits which should be forced to '0' */ | ||
122 | lnbp21->override_and = ~override_clear; | ||
123 | |||
124 | /* detect if it is present or not */ | ||
125 | if (lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF)) { | ||
126 | kfree(lnbp21); | ||
127 | fe->misc_priv = NULL; | ||
128 | return -EIO; | ||
129 | } | ||
130 | |||
131 | /* install release callback */ | ||
132 | lnbp21->release_chain = fe->ops.release; | ||
133 | fe->ops.release = lnbp21_release; | ||
134 | |||
135 | /* override frontend ops */ | ||
136 | fe->ops.set_voltage = lnbp21_set_voltage; | ||
137 | fe->ops.enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; | ||
138 | |||
139 | return 0; | ||
140 | } | ||
141 | EXPORT_SYMBOL(lnbp21_attach); | ||
142 | |||
143 | MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp21"); | ||
144 | MODULE_AUTHOR("Oliver Endriss"); | ||
145 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/frontends/lnbp21.h b/drivers/media/dvb/frontends/lnbp21.h index 0dcbe61b61b1..047a4ab68c01 100644 --- a/drivers/media/dvb/frontends/lnbp21.h +++ b/drivers/media/dvb/frontends/lnbp21.h | |||
@@ -27,7 +27,7 @@ | |||
27 | #ifndef _LNBP21_H | 27 | #ifndef _LNBP21_H |
28 | #define _LNBP21_H | 28 | #define _LNBP21_H |
29 | 29 | ||
30 | /* system register */ | 30 | /* system register bits */ |
31 | #define LNBP21_OLF 0x01 | 31 | #define LNBP21_OLF 0x01 |
32 | #define LNBP21_OTF 0x02 | 32 | #define LNBP21_OTF 0x02 |
33 | #define LNBP21_EN 0x04 | 33 | #define LNBP21_EN 0x04 |
@@ -37,103 +37,9 @@ | |||
37 | #define LNBP21_ISEL 0x40 | 37 | #define LNBP21_ISEL 0x40 |
38 | #define LNBP21_PCL 0x80 | 38 | #define LNBP21_PCL 0x80 |
39 | 39 | ||
40 | struct lnbp21 { | 40 | #include <linux/dvb/frontend.h> |
41 | u8 config; | ||
42 | u8 override_or; | ||
43 | u8 override_and; | ||
44 | struct i2c_adapter *i2c; | ||
45 | void (*release_chain)(struct dvb_frontend* fe); | ||
46 | }; | ||
47 | 41 | ||
48 | static int lnbp21_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | 42 | /* override_set and override_clear control which system register bits (above) to always set & clear */ |
49 | { | 43 | extern int lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear); |
50 | struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv; | ||
51 | struct i2c_msg msg = { .addr = 0x08, .flags = 0, | ||
52 | .buf = &lnbp21->config, | ||
53 | .len = sizeof(lnbp21->config) }; | ||
54 | |||
55 | lnbp21->config &= ~(LNBP21_VSEL | LNBP21_EN); | ||
56 | |||
57 | switch(voltage) { | ||
58 | case SEC_VOLTAGE_OFF: | ||
59 | break; | ||
60 | case SEC_VOLTAGE_13: | ||
61 | lnbp21->config |= LNBP21_EN; | ||
62 | break; | ||
63 | case SEC_VOLTAGE_18: | ||
64 | lnbp21->config |= (LNBP21_EN | LNBP21_VSEL); | ||
65 | break; | ||
66 | default: | ||
67 | return -EINVAL; | ||
68 | }; | ||
69 | |||
70 | lnbp21->config |= lnbp21->override_or; | ||
71 | lnbp21->config &= lnbp21->override_and; | ||
72 | |||
73 | return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO; | ||
74 | } | ||
75 | |||
76 | static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg) | ||
77 | { | ||
78 | struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv; | ||
79 | struct i2c_msg msg = { .addr = 0x08, .flags = 0, | ||
80 | .buf = &lnbp21->config, | ||
81 | .len = sizeof(lnbp21->config) }; | ||
82 | |||
83 | if (arg) | ||
84 | lnbp21->config |= LNBP21_LLC; | ||
85 | else | ||
86 | lnbp21->config &= ~LNBP21_LLC; | ||
87 | |||
88 | lnbp21->config |= lnbp21->override_or; | ||
89 | lnbp21->config &= lnbp21->override_and; | ||
90 | |||
91 | return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO; | ||
92 | } | ||
93 | |||
94 | static void lnbp21_exit(struct dvb_frontend *fe) | ||
95 | { | ||
96 | struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv; | ||
97 | |||
98 | /* LNBP power off */ | ||
99 | lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF); | ||
100 | |||
101 | /* free data & call next release routine */ | ||
102 | fe->ops->release = lnbp21->release_chain; | ||
103 | kfree(fe->misc_priv); | ||
104 | fe->misc_priv = NULL; | ||
105 | if (fe->ops->release) | ||
106 | fe->ops->release(fe); | ||
107 | } | ||
108 | |||
109 | static int lnbp21_init(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear) | ||
110 | { | ||
111 | struct lnbp21 *lnbp21 = kmalloc(sizeof(struct lnbp21), GFP_KERNEL); | ||
112 | |||
113 | if (!lnbp21) | ||
114 | return -ENOMEM; | ||
115 | |||
116 | /* default configuration */ | ||
117 | lnbp21->config = LNBP21_ISEL; | ||
118 | |||
119 | /* bits which should be forced to '1' */ | ||
120 | lnbp21->override_or = override_set; | ||
121 | |||
122 | /* bits which should be forced to '0' */ | ||
123 | lnbp21->override_and = ~override_clear; | ||
124 | |||
125 | /* install release callback */ | ||
126 | lnbp21->release_chain = fe->ops->release; | ||
127 | fe->ops->release = lnbp21_exit; | ||
128 | |||
129 | /* override frontend ops */ | ||
130 | fe->ops->set_voltage = lnbp21_set_voltage; | ||
131 | fe->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; | ||
132 | |||
133 | lnbp21->i2c = i2c; | ||
134 | fe->misc_priv = lnbp21; | ||
135 | |||
136 | return lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF); | ||
137 | } | ||
138 | 44 | ||
139 | #endif | 45 | #endif |
diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c index d3aea83cf218..1ef821825641 100644 --- a/drivers/media/dvb/frontends/mt312.c +++ b/drivers/media/dvb/frontends/mt312.c | |||
@@ -39,7 +39,6 @@ | |||
39 | 39 | ||
40 | struct mt312_state { | 40 | struct mt312_state { |
41 | struct i2c_adapter* i2c; | 41 | struct i2c_adapter* i2c; |
42 | struct dvb_frontend_ops ops; | ||
43 | /* configuration settings */ | 42 | /* configuration settings */ |
44 | const struct mt312_config* config; | 43 | const struct mt312_config* config; |
45 | struct dvb_frontend frontend; | 44 | struct dvb_frontend frontend; |
@@ -277,12 +276,6 @@ static int mt312_initfe(struct dvb_frontend* fe) | |||
277 | if ((ret = mt312_writereg(state, CS_SW_LIM, 0x69)) < 0) | 276 | if ((ret = mt312_writereg(state, CS_SW_LIM, 0x69)) < 0) |
278 | return ret; | 277 | return ret; |
279 | 278 | ||
280 | if (state->config->pll_init) { | ||
281 | mt312_writereg(state, GPP_CTRL, 0x40); | ||
282 | state->config->pll_init(fe); | ||
283 | mt312_writereg(state, GPP_CTRL, 0x00); | ||
284 | } | ||
285 | |||
286 | return 0; | 279 | return 0; |
287 | } | 280 | } |
288 | 281 | ||
@@ -477,16 +470,16 @@ static int mt312_set_frontend(struct dvb_frontend* fe, | |||
477 | 470 | ||
478 | dprintk("%s: Freq %d\n", __FUNCTION__, p->frequency); | 471 | dprintk("%s: Freq %d\n", __FUNCTION__, p->frequency); |
479 | 472 | ||
480 | if ((p->frequency < fe->ops->info.frequency_min) | 473 | if ((p->frequency < fe->ops.info.frequency_min) |
481 | || (p->frequency > fe->ops->info.frequency_max)) | 474 | || (p->frequency > fe->ops.info.frequency_max)) |
482 | return -EINVAL; | 475 | return -EINVAL; |
483 | 476 | ||
484 | if ((p->inversion < INVERSION_OFF) | 477 | if ((p->inversion < INVERSION_OFF) |
485 | || (p->inversion > INVERSION_ON)) | 478 | || (p->inversion > INVERSION_ON)) |
486 | return -EINVAL; | 479 | return -EINVAL; |
487 | 480 | ||
488 | if ((p->u.qpsk.symbol_rate < fe->ops->info.symbol_rate_min) | 481 | if ((p->u.qpsk.symbol_rate < fe->ops.info.symbol_rate_min) |
489 | || (p->u.qpsk.symbol_rate > fe->ops->info.symbol_rate_max)) | 482 | || (p->u.qpsk.symbol_rate > fe->ops.info.symbol_rate_max)) |
490 | return -EINVAL; | 483 | return -EINVAL; |
491 | 484 | ||
492 | if ((p->u.qpsk.fec_inner < FEC_NONE) | 485 | if ((p->u.qpsk.fec_inner < FEC_NONE) |
@@ -529,9 +522,10 @@ static int mt312_set_frontend(struct dvb_frontend* fe, | |||
529 | return -EINVAL; | 522 | return -EINVAL; |
530 | } | 523 | } |
531 | 524 | ||
532 | mt312_writereg(state, GPP_CTRL, 0x40); | 525 | if (fe->ops.tuner_ops.set_params) { |
533 | state->config->pll_set(fe, p); | 526 | fe->ops.tuner_ops.set_params(fe, p); |
534 | mt312_writereg(state, GPP_CTRL, 0x00); | 527 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); |
528 | } | ||
535 | 529 | ||
536 | /* sr = (u16)(sr * 256.0 / 1000000.0) */ | 530 | /* sr = (u16)(sr * 256.0 / 1000000.0) */ |
537 | sr = mt312_div(p->u.qpsk.symbol_rate * 4, 15625); | 531 | sr = mt312_div(p->u.qpsk.symbol_rate * 4, 15625); |
@@ -578,6 +572,17 @@ static int mt312_get_frontend(struct dvb_frontend* fe, | |||
578 | return 0; | 572 | return 0; |
579 | } | 573 | } |
580 | 574 | ||
575 | static int mt312_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) | ||
576 | { | ||
577 | struct mt312_state* state = fe->demodulator_priv; | ||
578 | |||
579 | if (enable) { | ||
580 | return mt312_writereg(state, GPP_CTRL, 0x40); | ||
581 | } else { | ||
582 | return mt312_writereg(state, GPP_CTRL, 0x00); | ||
583 | } | ||
584 | } | ||
585 | |||
581 | static int mt312_sleep(struct dvb_frontend* fe) | 586 | static int mt312_sleep(struct dvb_frontend* fe) |
582 | { | 587 | { |
583 | struct mt312_state *state = fe->demodulator_priv; | 588 | struct mt312_state *state = fe->demodulator_priv; |
@@ -633,6 +638,7 @@ static struct dvb_frontend_ops vp310_mt312_ops = { | |||
633 | 638 | ||
634 | .init = mt312_initfe, | 639 | .init = mt312_initfe, |
635 | .sleep = mt312_sleep, | 640 | .sleep = mt312_sleep, |
641 | .i2c_gate_ctrl = mt312_i2c_gate_ctrl, | ||
636 | 642 | ||
637 | .set_frontend = mt312_set_frontend, | 643 | .set_frontend = mt312_set_frontend, |
638 | .get_frontend = mt312_get_frontend, | 644 | .get_frontend = mt312_get_frontend, |
@@ -663,19 +669,22 @@ struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config, | |||
663 | /* setup the state */ | 669 | /* setup the state */ |
664 | state->config = config; | 670 | state->config = config; |
665 | state->i2c = i2c; | 671 | state->i2c = i2c; |
666 | memcpy(&state->ops, &vp310_mt312_ops, sizeof(struct dvb_frontend_ops)); | ||
667 | 672 | ||
668 | /* check if the demod is there */ | 673 | /* check if the demod is there */ |
669 | if (mt312_readreg(state, ID, &state->id) < 0) | 674 | if (mt312_readreg(state, ID, &state->id) < 0) |
670 | goto error; | 675 | goto error; |
671 | 676 | ||
677 | /* create dvb_frontend */ | ||
678 | memcpy(&state->frontend.ops, &vp310_mt312_ops, sizeof(struct dvb_frontend_ops)); | ||
679 | state->frontend.demodulator_priv = state; | ||
680 | |||
672 | switch (state->id) { | 681 | switch (state->id) { |
673 | case ID_VP310: | 682 | case ID_VP310: |
674 | strcpy(state->ops.info.name, "Zarlink VP310 DVB-S"); | 683 | strcpy(state->frontend.ops.info.name, "Zarlink VP310 DVB-S"); |
675 | state->frequency = 90; | 684 | state->frequency = 90; |
676 | break; | 685 | break; |
677 | case ID_MT312: | 686 | case ID_MT312: |
678 | strcpy(state->ops.info.name, "Zarlink MT312 DVB-S"); | 687 | strcpy(state->frontend.ops.info.name, "Zarlink MT312 DVB-S"); |
679 | state->frequency = 60; | 688 | state->frequency = 60; |
680 | break; | 689 | break; |
681 | default: | 690 | default: |
@@ -683,9 +692,6 @@ struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config, | |||
683 | goto error; | 692 | goto error; |
684 | } | 693 | } |
685 | 694 | ||
686 | /* create dvb_frontend */ | ||
687 | state->frontend.ops = &state->ops; | ||
688 | state->frontend.demodulator_priv = state; | ||
689 | return &state->frontend; | 695 | return &state->frontend; |
690 | 696 | ||
691 | error: | 697 | error: |
diff --git a/drivers/media/dvb/frontends/mt312.h b/drivers/media/dvb/frontends/mt312.h index 074d844f0139..666a1bd1c244 100644 --- a/drivers/media/dvb/frontends/mt312.h +++ b/drivers/media/dvb/frontends/mt312.h | |||
@@ -32,10 +32,6 @@ struct mt312_config | |||
32 | { | 32 | { |
33 | /* the demodulator's i2c address */ | 33 | /* the demodulator's i2c address */ |
34 | u8 demod_address; | 34 | u8 demod_address; |
35 | |||
36 | /* PLL maintenance */ | ||
37 | int (*pll_init)(struct dvb_frontend* fe); | ||
38 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
39 | }; | 35 | }; |
40 | 36 | ||
41 | struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config, | 37 | struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config, |
diff --git a/drivers/media/dvb/frontends/mt352.c b/drivers/media/dvb/frontends/mt352.c index aaaec909ddf8..5de7376c94ce 100644 --- a/drivers/media/dvb/frontends/mt352.c +++ b/drivers/media/dvb/frontends/mt352.c | |||
@@ -45,7 +45,6 @@ | |||
45 | struct mt352_state { | 45 | struct mt352_state { |
46 | struct i2c_adapter* i2c; | 46 | struct i2c_adapter* i2c; |
47 | struct dvb_frontend frontend; | 47 | struct dvb_frontend frontend; |
48 | struct dvb_frontend_ops ops; | ||
49 | 48 | ||
50 | /* configuration settings */ | 49 | /* configuration settings */ |
51 | struct mt352_config config; | 50 | struct mt352_config config; |
@@ -286,16 +285,25 @@ static int mt352_set_parameters(struct dvb_frontend* fe, | |||
286 | 285 | ||
287 | mt352_calc_nominal_rate(state, op->bandwidth, buf+4); | 286 | mt352_calc_nominal_rate(state, op->bandwidth, buf+4); |
288 | mt352_calc_input_freq(state, buf+6); | 287 | mt352_calc_input_freq(state, buf+6); |
289 | state->config.pll_set(fe, param, buf+8); | ||
290 | 288 | ||
291 | mt352_write(fe, buf, sizeof(buf)); | ||
292 | if (state->config.no_tuner) { | 289 | if (state->config.no_tuner) { |
293 | /* start decoding */ | 290 | if (fe->ops.tuner_ops.set_params) { |
291 | fe->ops.tuner_ops.set_params(fe, param); | ||
292 | if (fe->ops.i2c_gate_ctrl) | ||
293 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
294 | } | ||
295 | |||
296 | mt352_write(fe, buf, 8); | ||
294 | mt352_write(fe, fsm_go, 2); | 297 | mt352_write(fe, fsm_go, 2); |
295 | } else { | 298 | } else { |
296 | /* start tuning */ | 299 | if (fe->ops.tuner_ops.calc_regs) { |
297 | mt352_write(fe, tuner_go, 2); | 300 | fe->ops.tuner_ops.calc_regs(fe, param, buf+8, 5); |
301 | buf[8] <<= 1; | ||
302 | mt352_write(fe, buf, sizeof(buf)); | ||
303 | mt352_write(fe, tuner_go, 2); | ||
304 | } | ||
298 | } | 305 | } |
306 | |||
299 | return 0; | 307 | return 0; |
300 | } | 308 | } |
301 | 309 | ||
@@ -541,13 +549,12 @@ struct dvb_frontend* mt352_attach(const struct mt352_config* config, | |||
541 | /* setup the state */ | 549 | /* setup the state */ |
542 | state->i2c = i2c; | 550 | state->i2c = i2c; |
543 | memcpy(&state->config,config,sizeof(struct mt352_config)); | 551 | memcpy(&state->config,config,sizeof(struct mt352_config)); |
544 | memcpy(&state->ops, &mt352_ops, sizeof(struct dvb_frontend_ops)); | ||
545 | 552 | ||
546 | /* check if the demod is there */ | 553 | /* check if the demod is there */ |
547 | if (mt352_read_register(state, CHIP_ID) != ID_MT352) goto error; | 554 | if (mt352_read_register(state, CHIP_ID) != ID_MT352) goto error; |
548 | 555 | ||
549 | /* create dvb_frontend */ | 556 | /* create dvb_frontend */ |
550 | state->frontend.ops = &state->ops; | 557 | memcpy(&state->frontend.ops, &mt352_ops, sizeof(struct dvb_frontend_ops)); |
551 | state->frontend.demodulator_priv = state; | 558 | state->frontend.demodulator_priv = state; |
552 | return &state->frontend; | 559 | return &state->frontend; |
553 | 560 | ||
diff --git a/drivers/media/dvb/frontends/mt352.h b/drivers/media/dvb/frontends/mt352.h index 03040cd595bb..9e7ff4b8fe5f 100644 --- a/drivers/media/dvb/frontends/mt352.h +++ b/drivers/media/dvb/frontends/mt352.h | |||
@@ -49,12 +49,6 @@ struct mt352_config | |||
49 | 49 | ||
50 | /* Initialise the demodulator and PLL. Cannot be NULL */ | 50 | /* Initialise the demodulator and PLL. Cannot be NULL */ |
51 | int (*demod_init)(struct dvb_frontend* fe); | 51 | int (*demod_init)(struct dvb_frontend* fe); |
52 | |||
53 | /* PLL setup - fill out the supplied 5 byte buffer with your PLL settings. | ||
54 | * byte0: Set to pll i2c address (nonlinux; left shifted by 1) | ||
55 | * byte1-4: PLL configuration. | ||
56 | */ | ||
57 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf); | ||
58 | }; | 52 | }; |
59 | 53 | ||
60 | extern struct dvb_frontend* mt352_attach(const struct mt352_config* config, | 54 | extern struct dvb_frontend* mt352_attach(const struct mt352_config* config, |
diff --git a/drivers/media/dvb/frontends/nxt200x.c b/drivers/media/dvb/frontends/nxt200x.c index 9e3535394509..55671cb5255e 100644 --- a/drivers/media/dvb/frontends/nxt200x.c +++ b/drivers/media/dvb/frontends/nxt200x.c | |||
@@ -55,7 +55,6 @@ | |||
55 | struct nxt200x_state { | 55 | struct nxt200x_state { |
56 | 56 | ||
57 | struct i2c_adapter* i2c; | 57 | struct i2c_adapter* i2c; |
58 | struct dvb_frontend_ops ops; | ||
59 | const struct nxt200x_config* config; | 58 | const struct nxt200x_config* config; |
60 | struct dvb_frontend frontend; | 59 | struct dvb_frontend frontend; |
61 | 60 | ||
@@ -333,17 +332,17 @@ static int nxt200x_writetuner (struct nxt200x_state* state, u8* data) | |||
333 | 332 | ||
334 | dprintk("%s\n", __FUNCTION__); | 333 | dprintk("%s\n", __FUNCTION__); |
335 | 334 | ||
336 | dprintk("Tuner Bytes: %02X %02X %02X %02X\n", data[0], data[1], data[2], data[3]); | 335 | dprintk("Tuner Bytes: %02X %02X %02X %02X\n", data[1], data[2], data[3], data[4]); |
337 | 336 | ||
338 | /* if NXT2004, write directly to tuner. if NXT2002, write through NXT chip. | 337 | /* if NXT2004, write directly to tuner. if NXT2002, write through NXT chip. |
339 | * direct write is required for Philips TUV1236D and ALPS TDHU2 */ | 338 | * direct write is required for Philips TUV1236D and ALPS TDHU2 */ |
340 | switch (state->demod_chip) { | 339 | switch (state->demod_chip) { |
341 | case NXT2004: | 340 | case NXT2004: |
342 | if (i2c_writebytes(state, state->config->pll_address, data, 4)) | 341 | if (i2c_writebytes(state, data[0], data+1, 4)) |
343 | printk(KERN_WARNING "nxt200x: error writing to tuner\n"); | 342 | printk(KERN_WARNING "nxt200x: error writing to tuner\n"); |
344 | /* wait until we have a lock */ | 343 | /* wait until we have a lock */ |
345 | while (count < 20) { | 344 | while (count < 20) { |
346 | i2c_readbytes(state, state->config->pll_address, &buf, 1); | 345 | i2c_readbytes(state, data[0], &buf, 1); |
347 | if (buf & 0x40) | 346 | if (buf & 0x40) |
348 | return 0; | 347 | return 0; |
349 | msleep(100); | 348 | msleep(100); |
@@ -361,10 +360,10 @@ static int nxt200x_writetuner (struct nxt200x_state* state, u8* data) | |||
361 | nxt200x_writebytes(state, 0x34, &buf, 1); | 360 | nxt200x_writebytes(state, 0x34, &buf, 1); |
362 | 361 | ||
363 | /* write actual tuner bytes */ | 362 | /* write actual tuner bytes */ |
364 | nxt200x_writebytes(state, 0x36, data, 4); | 363 | nxt200x_writebytes(state, 0x36, data+1, 4); |
365 | 364 | ||
366 | /* set tuner i2c address */ | 365 | /* set tuner i2c address */ |
367 | buf = state->config->pll_address; | 366 | buf = data[0] << 1; |
368 | nxt200x_writebytes(state, 0x35, &buf, 1); | 367 | nxt200x_writebytes(state, 0x35, &buf, 1); |
369 | 368 | ||
370 | /* write UC Opmode to begin transfer */ | 369 | /* write UC Opmode to begin transfer */ |
@@ -534,7 +533,7 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe, | |||
534 | struct dvb_frontend_parameters *p) | 533 | struct dvb_frontend_parameters *p) |
535 | { | 534 | { |
536 | struct nxt200x_state* state = fe->demodulator_priv; | 535 | struct nxt200x_state* state = fe->demodulator_priv; |
537 | u8 buf[4]; | 536 | u8 buf[5]; |
538 | 537 | ||
539 | /* stop the micro first */ | 538 | /* stop the micro first */ |
540 | nxt200x_microcontroller_stop(state); | 539 | nxt200x_microcontroller_stop(state); |
@@ -548,7 +547,9 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe, | |||
548 | } | 547 | } |
549 | 548 | ||
550 | /* get tuning information */ | 549 | /* get tuning information */ |
551 | dvb_pll_configure(state->config->pll_desc, buf, p->frequency, 0); | 550 | if (fe->ops.tuner_ops.calc_regs) { |
551 | fe->ops.tuner_ops.calc_regs(fe, p, buf, 5); | ||
552 | } | ||
552 | 553 | ||
553 | /* set additional params */ | 554 | /* set additional params */ |
554 | switch (p->u.vsb.modulation) { | 555 | switch (p->u.vsb.modulation) { |
@@ -1159,7 +1160,6 @@ struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config, | |||
1159 | /* setup the state */ | 1160 | /* setup the state */ |
1160 | state->config = config; | 1161 | state->config = config; |
1161 | state->i2c = i2c; | 1162 | state->i2c = i2c; |
1162 | memcpy(&state->ops, &nxt200x_ops, sizeof(struct dvb_frontend_ops)); | ||
1163 | state->initialised = 0; | 1163 | state->initialised = 0; |
1164 | 1164 | ||
1165 | /* read card id */ | 1165 | /* read card id */ |
@@ -1198,7 +1198,7 @@ struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config, | |||
1198 | } | 1198 | } |
1199 | 1199 | ||
1200 | /* create dvb_frontend */ | 1200 | /* create dvb_frontend */ |
1201 | state->frontend.ops = &state->ops; | 1201 | memcpy(&state->frontend.ops, &nxt200x_ops, sizeof(struct dvb_frontend_ops)); |
1202 | state->frontend.demodulator_priv = state; | 1202 | state->frontend.demodulator_priv = state; |
1203 | return &state->frontend; | 1203 | return &state->frontend; |
1204 | 1204 | ||
diff --git a/drivers/media/dvb/frontends/nxt200x.h b/drivers/media/dvb/frontends/nxt200x.h index 1d9d70bc37ef..34d61735845b 100644 --- a/drivers/media/dvb/frontends/nxt200x.h +++ b/drivers/media/dvb/frontends/nxt200x.h | |||
@@ -38,10 +38,6 @@ struct nxt200x_config | |||
38 | /* the demodulator's i2c address */ | 38 | /* the demodulator's i2c address */ |
39 | u8 demod_address; | 39 | u8 demod_address; |
40 | 40 | ||
41 | /* tuner information */ | ||
42 | u8 pll_address; | ||
43 | struct dvb_pll_desc *pll_desc; | ||
44 | |||
45 | /* used to set pll input */ | 41 | /* used to set pll input */ |
46 | int (*set_pll_input)(u8* buf, int input); | 42 | int (*set_pll_input)(u8* buf, int input); |
47 | 43 | ||
diff --git a/drivers/media/dvb/frontends/nxt6000.c b/drivers/media/dvb/frontends/nxt6000.c index a16eeba0020d..d313d7dcf386 100644 --- a/drivers/media/dvb/frontends/nxt6000.c +++ b/drivers/media/dvb/frontends/nxt6000.c | |||
@@ -33,7 +33,6 @@ | |||
33 | 33 | ||
34 | struct nxt6000_state { | 34 | struct nxt6000_state { |
35 | struct i2c_adapter* i2c; | 35 | struct i2c_adapter* i2c; |
36 | struct dvb_frontend_ops ops; | ||
37 | /* configuration settings */ | 36 | /* configuration settings */ |
38 | const struct nxt6000_config* config; | 37 | const struct nxt6000_config* config; |
39 | struct dvb_frontend frontend; | 38 | struct dvb_frontend frontend; |
@@ -207,12 +206,6 @@ static void nxt6000_setup(struct dvb_frontend* fe) | |||
207 | nxt6000_writereg(state, SUB_DIAG_MODE_SEL, 0); | 206 | nxt6000_writereg(state, SUB_DIAG_MODE_SEL, 0); |
208 | 207 | ||
209 | nxt6000_writereg(state, TS_FORMAT, 0); | 208 | nxt6000_writereg(state, TS_FORMAT, 0); |
210 | |||
211 | if (state->config->pll_init) { | ||
212 | nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x01); /* open i2c bus switch */ | ||
213 | state->config->pll_init(fe); | ||
214 | nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x00); /* close i2c bus switch */ | ||
215 | } | ||
216 | } | 209 | } |
217 | 210 | ||
218 | static void nxt6000_dump_status(struct nxt6000_state *state) | 211 | static void nxt6000_dump_status(struct nxt6000_state *state) |
@@ -469,9 +462,10 @@ static int nxt6000_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par | |||
469 | struct nxt6000_state* state = fe->demodulator_priv; | 462 | struct nxt6000_state* state = fe->demodulator_priv; |
470 | int result; | 463 | int result; |
471 | 464 | ||
472 | nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x01); /* open i2c bus switch */ | 465 | if (fe->ops.tuner_ops.set_params) { |
473 | state->config->pll_set(fe, param); | 466 | fe->ops.tuner_ops.set_params(fe, param); |
474 | nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x00); /* close i2c bus switch */ | 467 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); |
468 | } | ||
475 | 469 | ||
476 | if ((result = nxt6000_set_bandwidth(state, param->u.ofdm.bandwidth)) < 0) | 470 | if ((result = nxt6000_set_bandwidth(state, param->u.ofdm.bandwidth)) < 0) |
477 | return result; | 471 | return result; |
@@ -532,6 +526,17 @@ static int nxt6000_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_fron | |||
532 | return 0; | 526 | return 0; |
533 | } | 527 | } |
534 | 528 | ||
529 | static int nxt6000_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) | ||
530 | { | ||
531 | struct nxt6000_state* state = fe->demodulator_priv; | ||
532 | |||
533 | if (enable) { | ||
534 | return nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x01); | ||
535 | } else { | ||
536 | return nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x00); | ||
537 | } | ||
538 | } | ||
539 | |||
535 | static struct dvb_frontend_ops nxt6000_ops; | 540 | static struct dvb_frontend_ops nxt6000_ops; |
536 | 541 | ||
537 | struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, | 542 | struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, |
@@ -546,13 +551,12 @@ struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, | |||
546 | /* setup the state */ | 551 | /* setup the state */ |
547 | state->config = config; | 552 | state->config = config; |
548 | state->i2c = i2c; | 553 | state->i2c = i2c; |
549 | memcpy(&state->ops, &nxt6000_ops, sizeof(struct dvb_frontend_ops)); | ||
550 | 554 | ||
551 | /* check if the demod is there */ | 555 | /* check if the demod is there */ |
552 | if (nxt6000_readreg(state, OFDM_MSC_REV) != NXT6000ASICDEVICE) goto error; | 556 | if (nxt6000_readreg(state, OFDM_MSC_REV) != NXT6000ASICDEVICE) goto error; |
553 | 557 | ||
554 | /* create dvb_frontend */ | 558 | /* create dvb_frontend */ |
555 | state->frontend.ops = &state->ops; | 559 | memcpy(&state->frontend.ops, &nxt6000_ops, sizeof(struct dvb_frontend_ops)); |
556 | state->frontend.demodulator_priv = state; | 560 | state->frontend.demodulator_priv = state; |
557 | return &state->frontend; | 561 | return &state->frontend; |
558 | 562 | ||
@@ -584,6 +588,7 @@ static struct dvb_frontend_ops nxt6000_ops = { | |||
584 | .release = nxt6000_release, | 588 | .release = nxt6000_release, |
585 | 589 | ||
586 | .init = nxt6000_init, | 590 | .init = nxt6000_init, |
591 | .i2c_gate_ctrl = nxt6000_i2c_gate_ctrl, | ||
587 | 592 | ||
588 | .get_tune_settings = nxt6000_fe_get_tune_settings, | 593 | .get_tune_settings = nxt6000_fe_get_tune_settings, |
589 | 594 | ||
diff --git a/drivers/media/dvb/frontends/nxt6000.h b/drivers/media/dvb/frontends/nxt6000.h index b7d9bead3002..117031d11708 100644 --- a/drivers/media/dvb/frontends/nxt6000.h +++ b/drivers/media/dvb/frontends/nxt6000.h | |||
@@ -31,10 +31,6 @@ struct nxt6000_config | |||
31 | 31 | ||
32 | /* should clock inversion be used? */ | 32 | /* should clock inversion be used? */ |
33 | u8 clock_inversion:1; | 33 | u8 clock_inversion:1; |
34 | |||
35 | /* PLL maintenance */ | ||
36 | int (*pll_init)(struct dvb_frontend* fe); | ||
37 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
38 | }; | 34 | }; |
39 | 35 | ||
40 | extern struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, | 36 | extern struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, |
diff --git a/drivers/media/dvb/frontends/or51132.c b/drivers/media/dvb/frontends/or51132.c index 80e0f28127b7..d20ab30c1e83 100644 --- a/drivers/media/dvb/frontends/or51132.c +++ b/drivers/media/dvb/frontends/or51132.c | |||
@@ -54,7 +54,6 @@ static int debug; | |||
54 | struct or51132_state | 54 | struct or51132_state |
55 | { | 55 | { |
56 | struct i2c_adapter* i2c; | 56 | struct i2c_adapter* i2c; |
57 | struct dvb_frontend_ops ops; | ||
58 | 57 | ||
59 | /* Configuration settings */ | 58 | /* Configuration settings */ |
60 | const struct or51132_config* config; | 59 | const struct or51132_config* config; |
@@ -106,9 +105,8 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware | |||
106 | { | 105 | { |
107 | struct or51132_state* state = fe->demodulator_priv; | 106 | struct or51132_state* state = fe->demodulator_priv; |
108 | static u8 run_buf[] = {0x7F,0x01}; | 107 | static u8 run_buf[] = {0x7F,0x01}; |
109 | static u8 get_ver_buf[] = {0x04,0x00,0x30,0x00,0x00}; | 108 | u8 rec_buf[8]; |
110 | u8 rec_buf[14]; | 109 | u8 cmd_buf[3]; |
111 | u8 cmd_buf[14]; | ||
112 | u32 firmwareAsize, firmwareBsize; | 110 | u32 firmwareAsize, firmwareBsize; |
113 | int i,ret; | 111 | int i,ret; |
114 | 112 | ||
@@ -157,7 +155,6 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware | |||
157 | cmd_buf[0] = 0x10; | 155 | cmd_buf[0] = 0x10; |
158 | cmd_buf[1] = 0x10; | 156 | cmd_buf[1] = 0x10; |
159 | cmd_buf[2] = 0x00; | 157 | cmd_buf[2] = 0x00; |
160 | cmd_buf[3] = 0x00; | ||
161 | msleep(20); /* 20ms */ | 158 | msleep(20); /* 20ms */ |
162 | if ((ret = i2c_writebytes(state,state->config->demod_address, | 159 | if ((ret = i2c_writebytes(state,state->config->demod_address, |
163 | cmd_buf,3))) { | 160 | cmd_buf,3))) { |
@@ -167,8 +164,6 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware | |||
167 | 164 | ||
168 | cmd_buf[0] = 0x04; | 165 | cmd_buf[0] = 0x04; |
169 | cmd_buf[1] = 0x17; | 166 | cmd_buf[1] = 0x17; |
170 | cmd_buf[2] = 0x00; | ||
171 | cmd_buf[3] = 0x00; | ||
172 | msleep(20); /* 20ms */ | 167 | msleep(20); /* 20ms */ |
173 | if ((ret = i2c_writebytes(state,state->config->demod_address, | 168 | if ((ret = i2c_writebytes(state,state->config->demod_address, |
174 | cmd_buf,2))) { | 169 | cmd_buf,2))) { |
@@ -178,8 +173,6 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware | |||
178 | 173 | ||
179 | cmd_buf[0] = 0x00; | 174 | cmd_buf[0] = 0x00; |
180 | cmd_buf[1] = 0x00; | 175 | cmd_buf[1] = 0x00; |
181 | cmd_buf[2] = 0x00; | ||
182 | cmd_buf[3] = 0x00; | ||
183 | msleep(20); /* 20ms */ | 176 | msleep(20); /* 20ms */ |
184 | if ((ret = i2c_writebytes(state,state->config->demod_address, | 177 | if ((ret = i2c_writebytes(state,state->config->demod_address, |
185 | cmd_buf,2))) { | 178 | cmd_buf,2))) { |
@@ -189,7 +182,11 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware | |||
189 | 182 | ||
190 | for(i=0;i<4;i++) { | 183 | for(i=0;i<4;i++) { |
191 | msleep(20); /* 20ms */ | 184 | msleep(20); /* 20ms */ |
192 | get_ver_buf[4] = i+1; | 185 | /* Once upon a time, this command might have had something |
186 | to do with getting the firmware version, but it's | ||
187 | not used anymore: | ||
188 | {0x04,0x00,0x30,0x00,i+1} */ | ||
189 | /* Read 8 bytes, two bytes at a time */ | ||
193 | if ((ret = i2c_readbytes(state,state->config->demod_address, | 190 | if ((ret = i2c_readbytes(state,state->config->demod_address, |
194 | &rec_buf[i*2],2))) { | 191 | &rec_buf[i*2],2))) { |
195 | printk(KERN_WARNING | 192 | printk(KERN_WARNING |
@@ -208,7 +205,6 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware | |||
208 | cmd_buf[0] = 0x10; | 205 | cmd_buf[0] = 0x10; |
209 | cmd_buf[1] = 0x00; | 206 | cmd_buf[1] = 0x00; |
210 | cmd_buf[2] = 0x00; | 207 | cmd_buf[2] = 0x00; |
211 | cmd_buf[3] = 0x00; | ||
212 | msleep(20); /* 20ms */ | 208 | msleep(20); /* 20ms */ |
213 | if ((ret = i2c_writebytes(state,state->config->demod_address, | 209 | if ((ret = i2c_writebytes(state,state->config->demod_address, |
214 | cmd_buf,3))) { | 210 | cmd_buf,3))) { |
@@ -243,7 +239,7 @@ static int or51132_sleep(struct dvb_frontend* fe) | |||
243 | static int or51132_setmode(struct dvb_frontend* fe) | 239 | static int or51132_setmode(struct dvb_frontend* fe) |
244 | { | 240 | { |
245 | struct or51132_state* state = fe->demodulator_priv; | 241 | struct or51132_state* state = fe->demodulator_priv; |
246 | unsigned char cmd_buf[4]; | 242 | unsigned char cmd_buf[3]; |
247 | 243 | ||
248 | dprintk("setmode %d\n",(int)state->current_modulation); | 244 | dprintk("setmode %d\n",(int)state->current_modulation); |
249 | /* set operation mode in Receiver 1 register; */ | 245 | /* set operation mode in Receiver 1 register; */ |
@@ -263,7 +259,6 @@ static int or51132_setmode(struct dvb_frontend* fe) | |||
263 | default: | 259 | default: |
264 | printk("setmode:Modulation set to unsupported value\n"); | 260 | printk("setmode:Modulation set to unsupported value\n"); |
265 | }; | 261 | }; |
266 | cmd_buf[3] = 0x00; | ||
267 | if (i2c_writebytes(state,state->config->demod_address, | 262 | if (i2c_writebytes(state,state->config->demod_address, |
268 | cmd_buf,3)) { | 263 | cmd_buf,3)) { |
269 | printk(KERN_WARNING "or51132: set_mode error 1\n"); | 264 | printk(KERN_WARNING "or51132: set_mode error 1\n"); |
@@ -301,7 +296,6 @@ static int or51132_setmode(struct dvb_frontend* fe) | |||
301 | default: | 296 | default: |
302 | printk("setmode: Modulation set to unsupported value\n"); | 297 | printk("setmode: Modulation set to unsupported value\n"); |
303 | }; | 298 | }; |
304 | cmd_buf[3] = 0x00; | ||
305 | msleep(20); /* 20ms */ | 299 | msleep(20); /* 20ms */ |
306 | if (i2c_writebytes(state,state->config->demod_address, | 300 | if (i2c_writebytes(state,state->config->demod_address, |
307 | cmd_buf,3)) { | 301 | cmd_buf,3)) { |
@@ -313,52 +307,65 @@ static int or51132_setmode(struct dvb_frontend* fe) | |||
313 | return 0; | 307 | return 0; |
314 | } | 308 | } |
315 | 309 | ||
310 | /* Some modulations use the same firmware. This classifies modulations | ||
311 | by the firmware they use. */ | ||
312 | #define MOD_FWCLASS_UNKNOWN 0 | ||
313 | #define MOD_FWCLASS_VSB 1 | ||
314 | #define MOD_FWCLASS_QAM 2 | ||
315 | static int modulation_fw_class(fe_modulation_t modulation) | ||
316 | { | ||
317 | switch(modulation) { | ||
318 | case VSB_8: | ||
319 | return MOD_FWCLASS_VSB; | ||
320 | case QAM_AUTO: | ||
321 | case QAM_64: | ||
322 | case QAM_256: | ||
323 | return MOD_FWCLASS_QAM; | ||
324 | default: | ||
325 | return MOD_FWCLASS_UNKNOWN; | ||
326 | } | ||
327 | } | ||
328 | |||
316 | static int or51132_set_parameters(struct dvb_frontend* fe, | 329 | static int or51132_set_parameters(struct dvb_frontend* fe, |
317 | struct dvb_frontend_parameters *param) | 330 | struct dvb_frontend_parameters *param) |
318 | { | 331 | { |
319 | int ret; | 332 | int ret; |
320 | u8 buf[4]; | ||
321 | struct or51132_state* state = fe->demodulator_priv; | 333 | struct or51132_state* state = fe->demodulator_priv; |
322 | const struct firmware *fw; | 334 | const struct firmware *fw; |
323 | 335 | const char *fwname; | |
324 | /* Change only if we are actually changing the modulation */ | 336 | int clock_mode; |
325 | if (state->current_modulation != param->u.vsb.modulation) { | 337 | |
326 | switch(param->u.vsb.modulation) { | 338 | /* Upload new firmware only if we need a different one */ |
327 | case VSB_8: | 339 | if (modulation_fw_class(state->current_modulation) != |
340 | modulation_fw_class(param->u.vsb.modulation)) { | ||
341 | switch(modulation_fw_class(param->u.vsb.modulation)) { | ||
342 | case MOD_FWCLASS_VSB: | ||
328 | dprintk("set_parameters VSB MODE\n"); | 343 | dprintk("set_parameters VSB MODE\n"); |
329 | printk("or51132: Waiting for firmware upload(%s)...\n", | 344 | fwname = OR51132_VSB_FIRMWARE; |
330 | OR51132_VSB_FIRMWARE); | 345 | |
331 | ret = request_firmware(&fw, OR51132_VSB_FIRMWARE, | ||
332 | &state->i2c->dev); | ||
333 | if (ret){ | ||
334 | printk(KERN_WARNING "or51132: No firmware up" | ||
335 | "loaded(timeout or file not found?)\n"); | ||
336 | return ret; | ||
337 | } | ||
338 | /* Set non-punctured clock for VSB */ | 346 | /* Set non-punctured clock for VSB */ |
339 | state->config->set_ts_params(fe, 0); | 347 | clock_mode = 0; |
340 | break; | 348 | break; |
341 | case QAM_AUTO: | 349 | case MOD_FWCLASS_QAM: |
342 | case QAM_64: | ||
343 | case QAM_256: | ||
344 | dprintk("set_parameters QAM MODE\n"); | 350 | dprintk("set_parameters QAM MODE\n"); |
345 | printk("or51132: Waiting for firmware upload(%s)...\n", | 351 | fwname = OR51132_QAM_FIRMWARE; |
346 | OR51132_QAM_FIRMWARE); | 352 | |
347 | ret = request_firmware(&fw, OR51132_QAM_FIRMWARE, | ||
348 | &state->i2c->dev); | ||
349 | if (ret){ | ||
350 | printk(KERN_WARNING "or51132: No firmware up" | ||
351 | "loaded(timeout or file not found?)\n"); | ||
352 | return ret; | ||
353 | } | ||
354 | /* Set punctured clock for QAM */ | 353 | /* Set punctured clock for QAM */ |
355 | state->config->set_ts_params(fe, 1); | 354 | clock_mode = 1; |
356 | break; | 355 | break; |
357 | default: | 356 | default: |
358 | printk("or51132:Modulation type(%d) UNSUPPORTED\n", | 357 | printk("or51132: Modulation type(%d) UNSUPPORTED\n", |
359 | param->u.vsb.modulation); | 358 | param->u.vsb.modulation); |
360 | return -1; | 359 | return -1; |
361 | }; | 360 | } |
361 | printk("or51132: Waiting for firmware upload(%s)...\n", | ||
362 | fwname); | ||
363 | ret = request_firmware(&fw, fwname, &state->i2c->dev); | ||
364 | if (ret) { | ||
365 | printk(KERN_WARNING "or51132: No firmware up" | ||
366 | "loaded(timeout or file not found?)\n"); | ||
367 | return ret; | ||
368 | } | ||
362 | ret = or51132_load_firmware(fe, fw); | 369 | ret = or51132_load_firmware(fe, fw); |
363 | release_firmware(fw); | 370 | release_firmware(fw); |
364 | if (ret) { | 371 | if (ret) { |
@@ -367,18 +374,18 @@ static int or51132_set_parameters(struct dvb_frontend* fe, | |||
367 | return ret; | 374 | return ret; |
368 | } | 375 | } |
369 | printk("or51132: Firmware upload complete.\n"); | 376 | printk("or51132: Firmware upload complete.\n"); |
370 | 377 | state->config->set_ts_params(fe, clock_mode); | |
378 | } | ||
379 | /* Change only if we are actually changing the modulation */ | ||
380 | if (state->current_modulation != param->u.vsb.modulation) { | ||
371 | state->current_modulation = param->u.vsb.modulation; | 381 | state->current_modulation = param->u.vsb.modulation; |
372 | or51132_setmode(fe); | 382 | or51132_setmode(fe); |
373 | } | 383 | } |
374 | 384 | ||
375 | dvb_pll_configure(state->config->pll_desc, buf, | 385 | if (fe->ops.tuner_ops.set_params) { |
376 | param->frequency, 0); | 386 | fe->ops.tuner_ops.set_params(fe, param); |
377 | dprintk("set_parameters tuner bytes: 0x%02x 0x%02x " | 387 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); |
378 | "0x%02x 0x%02x\n",buf[0],buf[1],buf[2],buf[3]); | 388 | } |
379 | if (i2c_writebytes(state, state->config->pll_address ,buf, 4)) | ||
380 | printk(KERN_WARNING "or51132: set_parameters error " | ||
381 | "writing to tuner\n"); | ||
382 | 389 | ||
383 | /* Set to current mode */ | 390 | /* Set to current mode */ |
384 | or51132_setmode(fe); | 391 | or51132_setmode(fe); |
@@ -388,6 +395,44 @@ static int or51132_set_parameters(struct dvb_frontend* fe, | |||
388 | return 0; | 395 | return 0; |
389 | } | 396 | } |
390 | 397 | ||
398 | static int or51132_get_parameters(struct dvb_frontend* fe, | ||
399 | struct dvb_frontend_parameters *param) | ||
400 | { | ||
401 | struct or51132_state* state = fe->demodulator_priv; | ||
402 | u8 buf[2]; | ||
403 | |||
404 | /* Receiver Status */ | ||
405 | buf[0]=0x04; | ||
406 | buf[1]=0x00; | ||
407 | msleep(30); /* 30ms */ | ||
408 | if (i2c_writebytes(state,state->config->demod_address,buf,2)) { | ||
409 | printk(KERN_WARNING "or51132: get_parameters write error\n"); | ||
410 | return -EREMOTEIO; | ||
411 | } | ||
412 | msleep(30); /* 30ms */ | ||
413 | if (i2c_readbytes(state,state->config->demod_address,buf,2)) { | ||
414 | printk(KERN_WARNING "or51132: get_parameters read error\n"); | ||
415 | return -EREMOTEIO; | ||
416 | } | ||
417 | switch(buf[0]) { | ||
418 | case 0x06: param->u.vsb.modulation = VSB_8; break; | ||
419 | case 0x43: param->u.vsb.modulation = QAM_64; break; | ||
420 | case 0x45: param->u.vsb.modulation = QAM_256; break; | ||
421 | default: | ||
422 | printk(KERN_WARNING "or51132: unknown status 0x%02x\n", | ||
423 | buf[0]); | ||
424 | return -EREMOTEIO; | ||
425 | } | ||
426 | |||
427 | /* FIXME: Read frequency from frontend, take AFC into account */ | ||
428 | param->frequency = state->current_frequency; | ||
429 | |||
430 | /* FIXME: How to read inversion setting? Receiver 6 register? */ | ||
431 | param->inversion = INVERSION_AUTO; | ||
432 | |||
433 | return 0; | ||
434 | } | ||
435 | |||
391 | static int or51132_read_status(struct dvb_frontend* fe, fe_status_t* status) | 436 | static int or51132_read_status(struct dvb_frontend* fe, fe_status_t* status) |
392 | { | 437 | { |
393 | struct or51132_state* state = fe->demodulator_priv; | 438 | struct or51132_state* state = fe->demodulator_priv; |
@@ -572,12 +617,11 @@ struct dvb_frontend* or51132_attach(const struct or51132_config* config, | |||
572 | /* Setup the state */ | 617 | /* Setup the state */ |
573 | state->config = config; | 618 | state->config = config; |
574 | state->i2c = i2c; | 619 | state->i2c = i2c; |
575 | memcpy(&state->ops, &or51132_ops, sizeof(struct dvb_frontend_ops)); | ||
576 | state->current_frequency = -1; | 620 | state->current_frequency = -1; |
577 | state->current_modulation = -1; | 621 | state->current_modulation = -1; |
578 | 622 | ||
579 | /* Create dvb_frontend */ | 623 | /* Create dvb_frontend */ |
580 | state->frontend.ops = &state->ops; | 624 | memcpy(&state->frontend.ops, &or51132_ops, sizeof(struct dvb_frontend_ops)); |
581 | state->frontend.demodulator_priv = state; | 625 | state->frontend.demodulator_priv = state; |
582 | return &state->frontend; | 626 | return &state->frontend; |
583 | 627 | ||
@@ -590,7 +634,7 @@ static struct dvb_frontend_ops or51132_ops = { | |||
590 | 634 | ||
591 | .info = { | 635 | .info = { |
592 | .name = "Oren OR51132 VSB/QAM Frontend", | 636 | .name = "Oren OR51132 VSB/QAM Frontend", |
593 | .type = FE_ATSC, | 637 | .type = FE_ATSC, |
594 | .frequency_min = 44000000, | 638 | .frequency_min = 44000000, |
595 | .frequency_max = 958000000, | 639 | .frequency_max = 958000000, |
596 | .frequency_stepsize = 166666, | 640 | .frequency_stepsize = 166666, |
@@ -606,6 +650,7 @@ static struct dvb_frontend_ops or51132_ops = { | |||
606 | .sleep = or51132_sleep, | 650 | .sleep = or51132_sleep, |
607 | 651 | ||
608 | .set_frontend = or51132_set_parameters, | 652 | .set_frontend = or51132_set_parameters, |
653 | .get_frontend = or51132_get_parameters, | ||
609 | .get_tune_settings = or51132_get_tune_settings, | 654 | .get_tune_settings = or51132_get_tune_settings, |
610 | 655 | ||
611 | .read_status = or51132_read_status, | 656 | .read_status = or51132_read_status, |
diff --git a/drivers/media/dvb/frontends/or51132.h b/drivers/media/dvb/frontends/or51132.h index 622cdd18381b..89658883abf5 100644 --- a/drivers/media/dvb/frontends/or51132.h +++ b/drivers/media/dvb/frontends/or51132.h | |||
@@ -29,8 +29,6 @@ struct or51132_config | |||
29 | { | 29 | { |
30 | /* The demodulator's i2c address */ | 30 | /* The demodulator's i2c address */ |
31 | u8 demod_address; | 31 | u8 demod_address; |
32 | u8 pll_address; | ||
33 | struct dvb_pll_desc *pll_desc; | ||
34 | 32 | ||
35 | /* Need to set device param for start_dma */ | 33 | /* Need to set device param for start_dma */ |
36 | int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); | 34 | int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); |
diff --git a/drivers/media/dvb/frontends/or51211.c b/drivers/media/dvb/frontends/or51211.c index 7c3aed1f546b..26bed616fabe 100644 --- a/drivers/media/dvb/frontends/or51211.c +++ b/drivers/media/dvb/frontends/or51211.c | |||
@@ -54,7 +54,6 @@ static u8 cmd_buf[] = {0x04,0x01,0x50,0x80,0x06}; // ATSC | |||
54 | struct or51211_state { | 54 | struct or51211_state { |
55 | 55 | ||
56 | struct i2c_adapter* i2c; | 56 | struct i2c_adapter* i2c; |
57 | struct dvb_frontend_ops ops; | ||
58 | 57 | ||
59 | /* Configuration settings */ | 58 | /* Configuration settings */ |
60 | const struct or51211_config* config; | 59 | const struct or51211_config* config; |
@@ -585,12 +584,11 @@ struct dvb_frontend* or51211_attach(const struct or51211_config* config, | |||
585 | /* Setup the state */ | 584 | /* Setup the state */ |
586 | state->config = config; | 585 | state->config = config; |
587 | state->i2c = i2c; | 586 | state->i2c = i2c; |
588 | memcpy(&state->ops, &or51211_ops, sizeof(struct dvb_frontend_ops)); | ||
589 | state->initialized = 0; | 587 | state->initialized = 0; |
590 | state->current_frequency = 0; | 588 | state->current_frequency = 0; |
591 | 589 | ||
592 | /* Create dvb_frontend */ | 590 | /* Create dvb_frontend */ |
593 | state->frontend.ops = &state->ops; | 591 | memcpy(&state->frontend.ops, &or51211_ops, sizeof(struct dvb_frontend_ops)); |
594 | state->frontend.demodulator_priv = state; | 592 | state->frontend.demodulator_priv = state; |
595 | return &state->frontend; | 593 | return &state->frontend; |
596 | 594 | ||
diff --git a/drivers/media/dvb/frontends/s5h1420.c b/drivers/media/dvb/frontends/s5h1420.c index d69477596921..2c2c344c4c64 100644 --- a/drivers/media/dvb/frontends/s5h1420.c +++ b/drivers/media/dvb/frontends/s5h1420.c | |||
@@ -38,7 +38,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
38 | 38 | ||
39 | struct s5h1420_state { | 39 | struct s5h1420_state { |
40 | struct i2c_adapter* i2c; | 40 | struct i2c_adapter* i2c; |
41 | struct dvb_frontend_ops ops; | ||
42 | const struct s5h1420_config* config; | 41 | const struct s5h1420_config* config; |
43 | struct dvb_frontend frontend; | 42 | struct dvb_frontend frontend; |
44 | 43 | ||
@@ -584,7 +583,6 @@ static int s5h1420_set_frontend(struct dvb_frontend* fe, | |||
584 | struct s5h1420_state* state = fe->demodulator_priv; | 583 | struct s5h1420_state* state = fe->demodulator_priv; |
585 | int frequency_delta; | 584 | int frequency_delta; |
586 | struct dvb_frontend_tune_settings fesettings; | 585 | struct dvb_frontend_tune_settings fesettings; |
587 | u32 tmp; | ||
588 | 586 | ||
589 | /* check if we should do a fast-tune */ | 587 | /* check if we should do a fast-tune */ |
590 | memcpy(&fesettings.parameters, p, sizeof(struct dvb_frontend_parameters)); | 588 | memcpy(&fesettings.parameters, p, sizeof(struct dvb_frontend_parameters)); |
@@ -596,10 +594,17 @@ static int s5h1420_set_frontend(struct dvb_frontend* fe, | |||
596 | (state->fec_inner == p->u.qpsk.fec_inner) && | 594 | (state->fec_inner == p->u.qpsk.fec_inner) && |
597 | (state->symbol_rate == p->u.qpsk.symbol_rate)) { | 595 | (state->symbol_rate == p->u.qpsk.symbol_rate)) { |
598 | 596 | ||
599 | if (state->config->pll_set) { | 597 | if (fe->ops.tuner_ops.set_params) { |
600 | s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1); | 598 | fe->ops.tuner_ops.set_params(fe, p); |
601 | state->config->pll_set(fe, p, &tmp); | 599 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); |
600 | } | ||
601 | if (fe->ops.tuner_ops.get_frequency) { | ||
602 | u32 tmp; | ||
603 | fe->ops.tuner_ops.get_frequency(fe, &tmp); | ||
604 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); | ||
602 | s5h1420_setfreqoffset(state, p->frequency - tmp); | 605 | s5h1420_setfreqoffset(state, p->frequency - tmp); |
606 | } else { | ||
607 | s5h1420_setfreqoffset(state, 0); | ||
603 | } | 608 | } |
604 | return 0; | 609 | return 0; |
605 | } | 610 | } |
@@ -646,9 +651,9 @@ static int s5h1420_set_frontend(struct dvb_frontend* fe, | |||
646 | s5h1420_writereg(state, 0x05, s5h1420_readreg(state, 0x05) | 1); | 651 | s5h1420_writereg(state, 0x05, s5h1420_readreg(state, 0x05) | 1); |
647 | 652 | ||
648 | /* set tuner PLL */ | 653 | /* set tuner PLL */ |
649 | if (state->config->pll_set) { | 654 | if (fe->ops.tuner_ops.set_params) { |
650 | s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1); | 655 | fe->ops.tuner_ops.set_params(fe, p); |
651 | state->config->pll_set(fe, p, &tmp); | 656 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); |
652 | s5h1420_setfreqoffset(state, 0); | 657 | s5h1420_setfreqoffset(state, 0); |
653 | } | 658 | } |
654 | 659 | ||
@@ -708,6 +713,17 @@ static int s5h1420_get_tune_settings(struct dvb_frontend* fe, | |||
708 | return 0; | 713 | return 0; |
709 | } | 714 | } |
710 | 715 | ||
716 | static int s5h1420_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) | ||
717 | { | ||
718 | struct s5h1420_state* state = fe->demodulator_priv; | ||
719 | |||
720 | if (enable) { | ||
721 | return s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1); | ||
722 | } else { | ||
723 | return s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) & 0xfe); | ||
724 | } | ||
725 | } | ||
726 | |||
711 | static int s5h1420_init (struct dvb_frontend* fe) | 727 | static int s5h1420_init (struct dvb_frontend* fe) |
712 | { | 728 | { |
713 | struct s5h1420_state* state = fe->demodulator_priv; | 729 | struct s5h1420_state* state = fe->demodulator_priv; |
@@ -717,13 +733,6 @@ static int s5h1420_init (struct dvb_frontend* fe) | |||
717 | msleep(10); | 733 | msleep(10); |
718 | s5h1420_reset(state); | 734 | s5h1420_reset(state); |
719 | 735 | ||
720 | /* init PLL */ | ||
721 | if (state->config->pll_init) { | ||
722 | s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1); | ||
723 | state->config->pll_init(fe); | ||
724 | s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) & 0xfe); | ||
725 | } | ||
726 | |||
727 | return 0; | 736 | return 0; |
728 | } | 737 | } |
729 | 738 | ||
@@ -756,7 +765,6 @@ struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config, | |||
756 | /* setup the state */ | 765 | /* setup the state */ |
757 | state->config = config; | 766 | state->config = config; |
758 | state->i2c = i2c; | 767 | state->i2c = i2c; |
759 | memcpy(&state->ops, &s5h1420_ops, sizeof(struct dvb_frontend_ops)); | ||
760 | state->postlocked = 0; | 768 | state->postlocked = 0; |
761 | state->fclk = 88000000; | 769 | state->fclk = 88000000; |
762 | state->tunedfreq = 0; | 770 | state->tunedfreq = 0; |
@@ -769,7 +777,7 @@ struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config, | |||
769 | goto error; | 777 | goto error; |
770 | 778 | ||
771 | /* create dvb_frontend */ | 779 | /* create dvb_frontend */ |
772 | state->frontend.ops = &state->ops; | 780 | memcpy(&state->frontend.ops, &s5h1420_ops, sizeof(struct dvb_frontend_ops)); |
773 | state->frontend.demodulator_priv = state; | 781 | state->frontend.demodulator_priv = state; |
774 | return &state->frontend; | 782 | return &state->frontend; |
775 | 783 | ||
@@ -800,6 +808,7 @@ static struct dvb_frontend_ops s5h1420_ops = { | |||
800 | 808 | ||
801 | .init = s5h1420_init, | 809 | .init = s5h1420_init, |
802 | .sleep = s5h1420_sleep, | 810 | .sleep = s5h1420_sleep, |
811 | .i2c_gate_ctrl = s5h1420_i2c_gate_ctrl, | ||
803 | 812 | ||
804 | .set_frontend = s5h1420_set_frontend, | 813 | .set_frontend = s5h1420_set_frontend, |
805 | .get_frontend = s5h1420_get_frontend, | 814 | .get_frontend = s5h1420_get_frontend, |
diff --git a/drivers/media/dvb/frontends/s5h1420.h b/drivers/media/dvb/frontends/s5h1420.h index 73296f13c324..4e39015fa67e 100644 --- a/drivers/media/dvb/frontends/s5h1420.h +++ b/drivers/media/dvb/frontends/s5h1420.h | |||
@@ -32,10 +32,6 @@ struct s5h1420_config | |||
32 | 32 | ||
33 | /* does the inversion require inversion? */ | 33 | /* does the inversion require inversion? */ |
34 | u8 invert:1; | 34 | u8 invert:1; |
35 | |||
36 | /* PLL maintenance */ | ||
37 | int (*pll_init)(struct dvb_frontend* fe); | ||
38 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u32* freqout); | ||
39 | }; | 35 | }; |
40 | 36 | ||
41 | extern struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config, | 37 | extern struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config, |
diff --git a/drivers/media/dvb/frontends/sp8870.c b/drivers/media/dvb/frontends/sp8870.c index 73829e647e50..44ec5b9a4695 100644 --- a/drivers/media/dvb/frontends/sp8870.c +++ b/drivers/media/dvb/frontends/sp8870.c | |||
@@ -44,8 +44,6 @@ struct sp8870_state { | |||
44 | 44 | ||
45 | struct i2c_adapter* i2c; | 45 | struct i2c_adapter* i2c; |
46 | 46 | ||
47 | struct dvb_frontend_ops ops; | ||
48 | |||
49 | const struct sp8870_config* config; | 47 | const struct sp8870_config* config; |
50 | 48 | ||
51 | struct dvb_frontend frontend; | 49 | struct dvb_frontend frontend; |
@@ -262,9 +260,10 @@ static int sp8870_set_frontend_parameters (struct dvb_frontend* fe, | |||
262 | sp8870_microcontroller_stop(state); | 260 | sp8870_microcontroller_stop(state); |
263 | 261 | ||
264 | // set tuner parameters | 262 | // set tuner parameters |
265 | sp8870_writereg(state, 0x206, 0x001); | 263 | if (fe->ops.tuner_ops.set_params) { |
266 | state->config->pll_set(fe, p); | 264 | fe->ops.tuner_ops.set_params(fe, p); |
267 | sp8870_writereg(state, 0x206, 0x000); | 265 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); |
266 | } | ||
268 | 267 | ||
269 | // sample rate correction bit [23..17] | 268 | // sample rate correction bit [23..17] |
270 | sp8870_writereg(state, 0x0319, 0x000A); | 269 | sp8870_writereg(state, 0x0319, 0x000A); |
@@ -349,13 +348,6 @@ static int sp8870_init (struct dvb_frontend* fe) | |||
349 | sp8870_writereg(state, 0x0D00, 0x010); | 348 | sp8870_writereg(state, 0x0D00, 0x010); |
350 | sp8870_writereg(state, 0x0D01, 0x000); | 349 | sp8870_writereg(state, 0x0D01, 0x000); |
351 | 350 | ||
352 | /* setup PLL */ | ||
353 | if (state->config->pll_init) { | ||
354 | sp8870_writereg(state, 0x206, 0x001); | ||
355 | state->config->pll_init(fe); | ||
356 | sp8870_writereg(state, 0x206, 0x000); | ||
357 | } | ||
358 | |||
359 | return 0; | 351 | return 0; |
360 | } | 352 | } |
361 | 353 | ||
@@ -541,6 +533,17 @@ static int sp8870_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend | |||
541 | return 0; | 533 | return 0; |
542 | } | 534 | } |
543 | 535 | ||
536 | static int sp8870_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) | ||
537 | { | ||
538 | struct sp8870_state* state = fe->demodulator_priv; | ||
539 | |||
540 | if (enable) { | ||
541 | return sp8870_writereg(state, 0x206, 0x001); | ||
542 | } else { | ||
543 | return sp8870_writereg(state, 0x206, 0x000); | ||
544 | } | ||
545 | } | ||
546 | |||
544 | static void sp8870_release(struct dvb_frontend* fe) | 547 | static void sp8870_release(struct dvb_frontend* fe) |
545 | { | 548 | { |
546 | struct sp8870_state* state = fe->demodulator_priv; | 549 | struct sp8870_state* state = fe->demodulator_priv; |
@@ -561,14 +564,13 @@ struct dvb_frontend* sp8870_attach(const struct sp8870_config* config, | |||
561 | /* setup the state */ | 564 | /* setup the state */ |
562 | state->config = config; | 565 | state->config = config; |
563 | state->i2c = i2c; | 566 | state->i2c = i2c; |
564 | memcpy(&state->ops, &sp8870_ops, sizeof(struct dvb_frontend_ops)); | ||
565 | state->initialised = 0; | 567 | state->initialised = 0; |
566 | 568 | ||
567 | /* check if the demod is there */ | 569 | /* check if the demod is there */ |
568 | if (sp8870_readreg(state, 0x0200) < 0) goto error; | 570 | if (sp8870_readreg(state, 0x0200) < 0) goto error; |
569 | 571 | ||
570 | /* create dvb_frontend */ | 572 | /* create dvb_frontend */ |
571 | state->frontend.ops = &state->ops; | 573 | memcpy(&state->frontend.ops, &sp8870_ops, sizeof(struct dvb_frontend_ops)); |
572 | state->frontend.demodulator_priv = state; | 574 | state->frontend.demodulator_priv = state; |
573 | return &state->frontend; | 575 | return &state->frontend; |
574 | 576 | ||
@@ -597,6 +599,7 @@ static struct dvb_frontend_ops sp8870_ops = { | |||
597 | 599 | ||
598 | .init = sp8870_init, | 600 | .init = sp8870_init, |
599 | .sleep = sp8870_sleep, | 601 | .sleep = sp8870_sleep, |
602 | .i2c_gate_ctrl = sp8870_i2c_gate_ctrl, | ||
600 | 603 | ||
601 | .set_frontend = sp8870_set_frontend, | 604 | .set_frontend = sp8870_set_frontend, |
602 | .get_tune_settings = sp8870_get_tune_settings, | 605 | .get_tune_settings = sp8870_get_tune_settings, |
diff --git a/drivers/media/dvb/frontends/sp8870.h b/drivers/media/dvb/frontends/sp8870.h index f3b555dbc960..93afbb969d6b 100644 --- a/drivers/media/dvb/frontends/sp8870.h +++ b/drivers/media/dvb/frontends/sp8870.h | |||
@@ -31,10 +31,6 @@ struct sp8870_config | |||
31 | /* the demodulator's i2c address */ | 31 | /* the demodulator's i2c address */ |
32 | u8 demod_address; | 32 | u8 demod_address; |
33 | 33 | ||
34 | /* PLL maintenance */ | ||
35 | int (*pll_init)(struct dvb_frontend* fe); | ||
36 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
37 | |||
38 | /* request firmware for device */ | 34 | /* request firmware for device */ |
39 | int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); | 35 | int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); |
40 | }; | 36 | }; |
diff --git a/drivers/media/dvb/frontends/sp887x.c b/drivers/media/dvb/frontends/sp887x.c index eb8a602198ca..b0a2b02f6608 100644 --- a/drivers/media/dvb/frontends/sp887x.c +++ b/drivers/media/dvb/frontends/sp887x.c | |||
@@ -24,7 +24,6 @@ | |||
24 | 24 | ||
25 | struct sp887x_state { | 25 | struct sp887x_state { |
26 | struct i2c_adapter* i2c; | 26 | struct i2c_adapter* i2c; |
27 | struct dvb_frontend_ops ops; | ||
28 | const struct sp887x_config* config; | 27 | const struct sp887x_config* config; |
29 | struct dvb_frontend frontend; | 28 | struct dvb_frontend frontend; |
30 | 29 | ||
@@ -208,15 +207,6 @@ static int sp887x_initial_setup (struct dvb_frontend* fe, const struct firmware | |||
208 | /* bit 0x010: enable data valid signal */ | 207 | /* bit 0x010: enable data valid signal */ |
209 | sp887x_writereg(state, 0xd00, 0x010); | 208 | sp887x_writereg(state, 0xd00, 0x010); |
210 | sp887x_writereg(state, 0x0d1, 0x000); | 209 | sp887x_writereg(state, 0x0d1, 0x000); |
211 | |||
212 | /* setup the PLL */ | ||
213 | if (state->config->pll_init) { | ||
214 | sp887x_writereg(state, 0x206, 0x001); | ||
215 | state->config->pll_init(fe); | ||
216 | sp887x_writereg(state, 0x206, 0x000); | ||
217 | } | ||
218 | |||
219 | printk ("done.\n"); | ||
220 | return 0; | 210 | return 0; |
221 | }; | 211 | }; |
222 | 212 | ||
@@ -362,9 +352,16 @@ static int sp887x_setup_frontend_parameters (struct dvb_frontend* fe, | |||
362 | sp887x_microcontroller_stop(state); | 352 | sp887x_microcontroller_stop(state); |
363 | 353 | ||
364 | /* setup the PLL */ | 354 | /* setup the PLL */ |
365 | sp887x_writereg(state, 0x206, 0x001); | 355 | if (fe->ops.tuner_ops.set_params) { |
366 | actual_freq = state->config->pll_set(fe, p); | 356 | fe->ops.tuner_ops.set_params(fe, p); |
367 | sp887x_writereg(state, 0x206, 0x000); | 357 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); |
358 | } | ||
359 | if (fe->ops.tuner_ops.get_frequency) { | ||
360 | fe->ops.tuner_ops.get_frequency(fe, &actual_freq); | ||
361 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); | ||
362 | } else { | ||
363 | actual_freq = p->frequency; | ||
364 | } | ||
368 | 365 | ||
369 | /* read status reg in order to clear <pending irqs */ | 366 | /* read status reg in order to clear <pending irqs */ |
370 | sp887x_readreg(state, 0x200); | 367 | sp887x_readreg(state, 0x200); |
@@ -486,6 +483,17 @@ static int sp887x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | |||
486 | return 0; | 483 | return 0; |
487 | } | 484 | } |
488 | 485 | ||
486 | static int sp887x_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) | ||
487 | { | ||
488 | struct sp887x_state* state = fe->demodulator_priv; | ||
489 | |||
490 | if (enable) { | ||
491 | return sp887x_writereg(state, 0x206, 0x001); | ||
492 | } else { | ||
493 | return sp887x_writereg(state, 0x206, 0x000); | ||
494 | } | ||
495 | } | ||
496 | |||
489 | static int sp887x_sleep(struct dvb_frontend* fe) | 497 | static int sp887x_sleep(struct dvb_frontend* fe) |
490 | { | 498 | { |
491 | struct sp887x_state* state = fe->demodulator_priv; | 499 | struct sp887x_state* state = fe->demodulator_priv; |
@@ -555,14 +563,13 @@ struct dvb_frontend* sp887x_attach(const struct sp887x_config* config, | |||
555 | /* setup the state */ | 563 | /* setup the state */ |
556 | state->config = config; | 564 | state->config = config; |
557 | state->i2c = i2c; | 565 | state->i2c = i2c; |
558 | memcpy(&state->ops, &sp887x_ops, sizeof(struct dvb_frontend_ops)); | ||
559 | state->initialised = 0; | 566 | state->initialised = 0; |
560 | 567 | ||
561 | /* check if the demod is there */ | 568 | /* check if the demod is there */ |
562 | if (sp887x_readreg(state, 0x0200) < 0) goto error; | 569 | if (sp887x_readreg(state, 0x0200) < 0) goto error; |
563 | 570 | ||
564 | /* create dvb_frontend */ | 571 | /* create dvb_frontend */ |
565 | state->frontend.ops = &state->ops; | 572 | memcpy(&state->frontend.ops, &sp887x_ops, sizeof(struct dvb_frontend_ops)); |
566 | state->frontend.demodulator_priv = state; | 573 | state->frontend.demodulator_priv = state; |
567 | return &state->frontend; | 574 | return &state->frontend; |
568 | 575 | ||
@@ -589,6 +596,7 @@ static struct dvb_frontend_ops sp887x_ops = { | |||
589 | 596 | ||
590 | .init = sp887x_init, | 597 | .init = sp887x_init, |
591 | .sleep = sp887x_sleep, | 598 | .sleep = sp887x_sleep, |
599 | .i2c_gate_ctrl = sp887x_i2c_gate_ctrl, | ||
592 | 600 | ||
593 | .set_frontend = sp887x_setup_frontend_parameters, | 601 | .set_frontend = sp887x_setup_frontend_parameters, |
594 | .get_tune_settings = sp887x_get_tune_settings, | 602 | .get_tune_settings = sp887x_get_tune_settings, |
diff --git a/drivers/media/dvb/frontends/sp887x.h b/drivers/media/dvb/frontends/sp887x.h index 6a05d8f8e8cc..c44b0ebdf1e2 100644 --- a/drivers/media/dvb/frontends/sp887x.h +++ b/drivers/media/dvb/frontends/sp887x.h | |||
@@ -13,12 +13,6 @@ struct sp887x_config | |||
13 | /* the demodulator's i2c address */ | 13 | /* the demodulator's i2c address */ |
14 | u8 demod_address; | 14 | u8 demod_address; |
15 | 15 | ||
16 | /* PLL maintenance */ | ||
17 | int (*pll_init)(struct dvb_frontend* fe); | ||
18 | |||
19 | /* this should return the actual frequency tuned to */ | ||
20 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
21 | |||
22 | /* request firmware for device */ | 16 | /* request firmware for device */ |
23 | int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); | 17 | int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); |
24 | }; | 18 | }; |
diff --git a/drivers/media/dvb/frontends/stv0297.c b/drivers/media/dvb/frontends/stv0297.c index eb15676d374f..1ca64249010c 100644 --- a/drivers/media/dvb/frontends/stv0297.c +++ b/drivers/media/dvb/frontends/stv0297.c | |||
@@ -32,7 +32,6 @@ | |||
32 | 32 | ||
33 | struct stv0297_state { | 33 | struct stv0297_state { |
34 | struct i2c_adapter *i2c; | 34 | struct i2c_adapter *i2c; |
35 | struct dvb_frontend_ops ops; | ||
36 | const struct stv0297_config *config; | 35 | const struct stv0297_config *config; |
37 | struct dvb_frontend frontend; | 36 | struct dvb_frontend frontend; |
38 | 37 | ||
@@ -68,19 +67,25 @@ static int stv0297_readreg(struct stv0297_state *state, u8 reg) | |||
68 | int ret; | 67 | int ret; |
69 | u8 b0[] = { reg }; | 68 | u8 b0[] = { reg }; |
70 | u8 b1[] = { 0 }; | 69 | u8 b1[] = { 0 }; |
71 | struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = | 70 | struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = 1}, |
72 | 1}, | 71 | {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1} |
73 | {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1} | 72 | }; |
74 | }; | ||
75 | 73 | ||
76 | // this device needs a STOP between the register and data | 74 | // this device needs a STOP between the register and data |
77 | if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) { | 75 | if (state->config->stop_during_read) { |
78 | dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret); | 76 | if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) { |
79 | return -1; | 77 | dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret); |
80 | } | 78 | return -1; |
81 | if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) { | 79 | } |
82 | dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret); | 80 | if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) { |
83 | return -1; | 81 | dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret); |
82 | return -1; | ||
83 | } | ||
84 | } else { | ||
85 | if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) { | ||
86 | dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret); | ||
87 | return -1; | ||
88 | } | ||
84 | } | 89 | } |
85 | 90 | ||
86 | return b1[0]; | 91 | return b1[0]; |
@@ -107,13 +112,20 @@ static int stv0297_readregs(struct stv0297_state *state, u8 reg1, u8 * b, u8 len | |||
107 | }; | 112 | }; |
108 | 113 | ||
109 | // this device needs a STOP between the register and data | 114 | // this device needs a STOP between the register and data |
110 | if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) { | 115 | if (state->config->stop_during_read) { |
111 | dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret); | 116 | if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) { |
112 | return -1; | 117 | dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret); |
113 | } | 118 | return -1; |
114 | if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) { | 119 | } |
115 | dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret); | 120 | if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) { |
116 | return -1; | 121 | dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret); |
122 | return -1; | ||
123 | } | ||
124 | } else { | ||
125 | if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) { | ||
126 | dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret); | ||
127 | return -1; | ||
128 | } | ||
117 | } | 129 | } |
118 | 130 | ||
119 | return 0; | 131 | return 0; |
@@ -276,12 +288,14 @@ static int stv0297_set_inversion(struct stv0297_state *state, fe_spectral_invers | |||
276 | return 0; | 288 | return 0; |
277 | } | 289 | } |
278 | 290 | ||
279 | int stv0297_enable_plli2c(struct dvb_frontend *fe) | 291 | static int stv0297_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) |
280 | { | 292 | { |
281 | struct stv0297_state *state = fe->demodulator_priv; | 293 | struct stv0297_state *state = fe->demodulator_priv; |
282 | 294 | ||
283 | stv0297_writereg(state, 0x87, 0x78); | 295 | if (enable) { |
284 | stv0297_writereg(state, 0x86, 0xc8); | 296 | stv0297_writereg(state, 0x87, 0x78); |
297 | stv0297_writereg(state, 0x86, 0xc8); | ||
298 | } | ||
285 | 299 | ||
286 | return 0; | 300 | return 0; |
287 | } | 301 | } |
@@ -296,9 +310,6 @@ static int stv0297_init(struct dvb_frontend *fe) | |||
296 | stv0297_writereg(state, state->config->inittab[i], state->config->inittab[i+1]); | 310 | stv0297_writereg(state, state->config->inittab[i], state->config->inittab[i+1]); |
297 | msleep(200); | 311 | msleep(200); |
298 | 312 | ||
299 | if (state->config->pll_init) | ||
300 | state->config->pll_init(fe); | ||
301 | |||
302 | return 0; | 313 | return 0; |
303 | } | 314 | } |
304 | 315 | ||
@@ -389,7 +400,7 @@ static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par | |||
389 | case QAM_32: | 400 | case QAM_32: |
390 | case QAM_64: | 401 | case QAM_64: |
391 | delay = 100; | 402 | delay = 100; |
392 | sweeprate = 1500; | 403 | sweeprate = 1000; |
393 | break; | 404 | break; |
394 | 405 | ||
395 | case QAM_128: | 406 | case QAM_128: |
@@ -421,7 +432,10 @@ static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par | |||
421 | } | 432 | } |
422 | 433 | ||
423 | stv0297_init(fe); | 434 | stv0297_init(fe); |
424 | state->config->pll_set(fe, p); | 435 | if (fe->ops.tuner_ops.set_params) { |
436 | fe->ops.tuner_ops.set_params(fe, p); | ||
437 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); | ||
438 | } | ||
425 | 439 | ||
426 | /* clear software interrupts */ | 440 | /* clear software interrupts */ |
427 | stv0297_writereg(state, 0x82, 0x0); | 441 | stv0297_writereg(state, 0x82, 0x0); |
@@ -634,7 +648,6 @@ struct dvb_frontend *stv0297_attach(const struct stv0297_config *config, | |||
634 | /* setup the state */ | 648 | /* setup the state */ |
635 | state->config = config; | 649 | state->config = config; |
636 | state->i2c = i2c; | 650 | state->i2c = i2c; |
637 | memcpy(&state->ops, &stv0297_ops, sizeof(struct dvb_frontend_ops)); | ||
638 | state->base_freq = 0; | 651 | state->base_freq = 0; |
639 | 652 | ||
640 | /* check if the demod is there */ | 653 | /* check if the demod is there */ |
@@ -642,7 +655,7 @@ struct dvb_frontend *stv0297_attach(const struct stv0297_config *config, | |||
642 | goto error; | 655 | goto error; |
643 | 656 | ||
644 | /* create dvb_frontend */ | 657 | /* create dvb_frontend */ |
645 | state->frontend.ops = &state->ops; | 658 | memcpy(&state->frontend.ops, &stv0297_ops, sizeof(struct dvb_frontend_ops)); |
646 | state->frontend.demodulator_priv = state; | 659 | state->frontend.demodulator_priv = state; |
647 | return &state->frontend; | 660 | return &state->frontend; |
648 | 661 | ||
@@ -668,6 +681,7 @@ static struct dvb_frontend_ops stv0297_ops = { | |||
668 | 681 | ||
669 | .init = stv0297_init, | 682 | .init = stv0297_init, |
670 | .sleep = stv0297_sleep, | 683 | .sleep = stv0297_sleep, |
684 | .i2c_gate_ctrl = stv0297_i2c_gate_ctrl, | ||
671 | 685 | ||
672 | .set_frontend = stv0297_set_frontend, | 686 | .set_frontend = stv0297_set_frontend, |
673 | .get_frontend = stv0297_get_frontend, | 687 | .get_frontend = stv0297_get_frontend, |
@@ -684,4 +698,3 @@ MODULE_AUTHOR("Dennis Noermann and Andrew de Quincey"); | |||
684 | MODULE_LICENSE("GPL"); | 698 | MODULE_LICENSE("GPL"); |
685 | 699 | ||
686 | EXPORT_SYMBOL(stv0297_attach); | 700 | EXPORT_SYMBOL(stv0297_attach); |
687 | EXPORT_SYMBOL(stv0297_enable_plli2c); | ||
diff --git a/drivers/media/dvb/frontends/stv0297.h b/drivers/media/dvb/frontends/stv0297.h index 9e53f019db71..1da5384fb985 100644 --- a/drivers/media/dvb/frontends/stv0297.h +++ b/drivers/media/dvb/frontends/stv0297.h | |||
@@ -38,13 +38,11 @@ struct stv0297_config | |||
38 | /* does the "inversion" need inverted? */ | 38 | /* does the "inversion" need inverted? */ |
39 | u8 invert:1; | 39 | u8 invert:1; |
40 | 40 | ||
41 | /* PLL maintenance */ | 41 | /* set to 1 if the device requires an i2c STOP during reading */ |
42 | int (*pll_init)(struct dvb_frontend* fe); | 42 | u8 stop_during_read:1; |
43 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
44 | }; | 43 | }; |
45 | 44 | ||
46 | extern struct dvb_frontend* stv0297_attach(const struct stv0297_config* config, | 45 | extern struct dvb_frontend* stv0297_attach(const struct stv0297_config* config, |
47 | struct i2c_adapter* i2c); | 46 | struct i2c_adapter* i2c); |
48 | extern int stv0297_enable_plli2c(struct dvb_frontend* fe); | ||
49 | 47 | ||
50 | #endif // STV0297_H | 48 | #endif // STV0297_H |
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c index 5bcd00f792e6..96648a75440d 100644 --- a/drivers/media/dvb/frontends/stv0299.c +++ b/drivers/media/dvb/frontends/stv0299.c | |||
@@ -56,7 +56,6 @@ | |||
56 | 56 | ||
57 | struct stv0299_state { | 57 | struct stv0299_state { |
58 | struct i2c_adapter* i2c; | 58 | struct i2c_adapter* i2c; |
59 | struct dvb_frontend_ops ops; | ||
60 | const struct stv0299_config* config; | 59 | const struct stv0299_config* config; |
61 | struct dvb_frontend frontend; | 60 | struct dvb_frontend frontend; |
62 | 61 | ||
@@ -131,13 +130,6 @@ static int stv0299_readregs (struct stv0299_state* state, u8 reg1, u8 *b, u8 len | |||
131 | return ret == 2 ? 0 : ret; | 130 | return ret == 2 ? 0 : ret; |
132 | } | 131 | } |
133 | 132 | ||
134 | int stv0299_enable_plli2c (struct dvb_frontend* fe) | ||
135 | { | ||
136 | struct stv0299_state* state = fe->demodulator_priv; | ||
137 | |||
138 | return stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */ | ||
139 | } | ||
140 | |||
141 | static int stv0299_set_FEC (struct stv0299_state* state, fe_code_rate_t fec) | 133 | static int stv0299_set_FEC (struct stv0299_state* state, fe_code_rate_t fec) |
142 | { | 134 | { |
143 | dprintk ("%s\n", __FUNCTION__); | 135 | dprintk ("%s\n", __FUNCTION__); |
@@ -457,12 +449,6 @@ static int stv0299_init (struct dvb_frontend* fe) | |||
457 | for (i=0; !(state->config->inittab[i] == 0xff && state->config->inittab[i+1] == 0xff); i+=2) | 449 | for (i=0; !(state->config->inittab[i] == 0xff && state->config->inittab[i+1] == 0xff); i+=2) |
458 | stv0299_writeregI(state, state->config->inittab[i], state->config->inittab[i+1]); | 450 | stv0299_writeregI(state, state->config->inittab[i], state->config->inittab[i+1]); |
459 | 451 | ||
460 | if (state->config->pll_init) { | ||
461 | stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */ | ||
462 | state->config->pll_init(fe, state->i2c); | ||
463 | stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */ | ||
464 | } | ||
465 | |||
466 | return 0; | 452 | return 0; |
467 | } | 453 | } |
468 | 454 | ||
@@ -560,9 +546,10 @@ static int stv0299_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par | |||
560 | if (state->config->invert) invval = (~invval) & 1; | 546 | if (state->config->invert) invval = (~invval) & 1; |
561 | stv0299_writeregI(state, 0x0c, (stv0299_readreg(state, 0x0c) & 0xfe) | invval); | 547 | stv0299_writeregI(state, 0x0c, (stv0299_readreg(state, 0x0c) & 0xfe) | invval); |
562 | 548 | ||
563 | stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */ | 549 | if (fe->ops.tuner_ops.set_params) { |
564 | state->config->pll_set(fe, state->i2c, p); | 550 | fe->ops.tuner_ops.set_params(fe, p); |
565 | stv0299_writeregI(state, 0x05, 0x35); /* disable i2c repeater on stv0299 */ | 551 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); |
552 | } | ||
566 | 553 | ||
567 | stv0299_set_FEC (state, p->u.qpsk.fec_inner); | 554 | stv0299_set_FEC (state, p->u.qpsk.fec_inner); |
568 | stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate); | 555 | stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate); |
@@ -611,6 +598,19 @@ static int stv0299_sleep(struct dvb_frontend* fe) | |||
611 | return 0; | 598 | return 0; |
612 | } | 599 | } |
613 | 600 | ||
601 | static int stv0299_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) | ||
602 | { | ||
603 | struct stv0299_state* state = fe->demodulator_priv; | ||
604 | |||
605 | if (enable) { | ||
606 | stv0299_writeregI(state, 0x05, 0xb5); | ||
607 | } else { | ||
608 | stv0299_writeregI(state, 0x05, 0x35); | ||
609 | } | ||
610 | udelay(1); | ||
611 | return 0; | ||
612 | } | ||
613 | |||
614 | static int stv0299_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) | 614 | static int stv0299_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) |
615 | { | 615 | { |
616 | struct stv0299_state* state = fe->demodulator_priv; | 616 | struct stv0299_state* state = fe->demodulator_priv; |
@@ -647,7 +647,6 @@ struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, | |||
647 | /* setup the state */ | 647 | /* setup the state */ |
648 | state->config = config; | 648 | state->config = config; |
649 | state->i2c = i2c; | 649 | state->i2c = i2c; |
650 | memcpy(&state->ops, &stv0299_ops, sizeof(struct dvb_frontend_ops)); | ||
651 | state->initialised = 0; | 650 | state->initialised = 0; |
652 | state->tuner_frequency = 0; | 651 | state->tuner_frequency = 0; |
653 | state->symbol_rate = 0; | 652 | state->symbol_rate = 0; |
@@ -664,7 +663,7 @@ struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, | |||
664 | if (id != 0xa1 && id != 0x80) goto error; | 663 | if (id != 0xa1 && id != 0x80) goto error; |
665 | 664 | ||
666 | /* create dvb_frontend */ | 665 | /* create dvb_frontend */ |
667 | state->frontend.ops = &state->ops; | 666 | memcpy(&state->frontend.ops, &stv0299_ops, sizeof(struct dvb_frontend_ops)); |
668 | state->frontend.demodulator_priv = state; | 667 | state->frontend.demodulator_priv = state; |
669 | return &state->frontend; | 668 | return &state->frontend; |
670 | 669 | ||
@@ -695,6 +694,7 @@ static struct dvb_frontend_ops stv0299_ops = { | |||
695 | 694 | ||
696 | .init = stv0299_init, | 695 | .init = stv0299_init, |
697 | .sleep = stv0299_sleep, | 696 | .sleep = stv0299_sleep, |
697 | .i2c_gate_ctrl = stv0299_i2c_gate_ctrl, | ||
698 | 698 | ||
699 | .set_frontend = stv0299_set_frontend, | 699 | .set_frontend = stv0299_set_frontend, |
700 | .get_frontend = stv0299_get_frontend, | 700 | .get_frontend = stv0299_get_frontend, |
@@ -721,9 +721,8 @@ MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); | |||
721 | 721 | ||
722 | MODULE_DESCRIPTION("ST STV0299 DVB Demodulator driver"); | 722 | MODULE_DESCRIPTION("ST STV0299 DVB Demodulator driver"); |
723 | MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Peter Schildmann, Felix Domke, " | 723 | MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Peter Schildmann, Felix Domke, " |
724 | "Andreas Oberritter, Andrew de Quincey, Kenneth Aafløy"); | 724 | "Andreas Oberritter, Andrew de Quincey, Kenneth Aafly"); |
725 | MODULE_LICENSE("GPL"); | 725 | MODULE_LICENSE("GPL"); |
726 | 726 | ||
727 | EXPORT_SYMBOL(stv0299_enable_plli2c); | ||
728 | EXPORT_SYMBOL(stv0299_writereg); | 727 | EXPORT_SYMBOL(stv0299_writereg); |
729 | EXPORT_SYMBOL(stv0299_attach); | 728 | EXPORT_SYMBOL(stv0299_attach); |
diff --git a/drivers/media/dvb/frontends/stv0299.h b/drivers/media/dvb/frontends/stv0299.h index 32c87b4c2f13..1504828e4232 100644 --- a/drivers/media/dvb/frontends/stv0299.h +++ b/drivers/media/dvb/frontends/stv0299.h | |||
@@ -87,14 +87,9 @@ struct stv0299_config | |||
87 | 87 | ||
88 | /* Set the symbol rate */ | 88 | /* Set the symbol rate */ |
89 | int (*set_symbol_rate)(struct dvb_frontend* fe, u32 srate, u32 ratio); | 89 | int (*set_symbol_rate)(struct dvb_frontend* fe, u32 srate, u32 ratio); |
90 | |||
91 | /* PLL maintenance */ | ||
92 | int (*pll_init)(struct dvb_frontend *fe, struct i2c_adapter *i2c); | ||
93 | int (*pll_set)(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters *params); | ||
94 | }; | 90 | }; |
95 | 91 | ||
96 | extern int stv0299_writereg (struct dvb_frontend* fe, u8 reg, u8 data); | 92 | extern int stv0299_writereg (struct dvb_frontend* fe, u8 reg, u8 data); |
97 | extern int stv0299_enable_plli2c (struct dvb_frontend* fe); | ||
98 | 93 | ||
99 | extern struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, | 94 | extern struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, |
100 | struct i2c_adapter* i2c); | 95 | struct i2c_adapter* i2c); |
diff --git a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb/frontends/tda10021.c index 21255cac9793..e83ff2104c9b 100644 --- a/drivers/media/dvb/frontends/tda10021.c +++ b/drivers/media/dvb/frontends/tda10021.c | |||
@@ -36,7 +36,6 @@ | |||
36 | 36 | ||
37 | struct tda10021_state { | 37 | struct tda10021_state { |
38 | struct i2c_adapter* i2c; | 38 | struct i2c_adapter* i2c; |
39 | struct dvb_frontend_ops ops; | ||
40 | /* configuration settings */ | 39 | /* configuration settings */ |
41 | const struct tda10021_config* config; | 40 | const struct tda10021_config* config; |
42 | struct dvb_frontend frontend; | 41 | struct dvb_frontend frontend; |
@@ -90,6 +89,14 @@ static int tda10021_writereg (struct tda10021_state* state, u8 reg, u8 data) | |||
90 | return (ret != 1) ? -EREMOTEIO : 0; | 89 | return (ret != 1) ? -EREMOTEIO : 0; |
91 | } | 90 | } |
92 | 91 | ||
92 | int tda10021_write_byte(struct dvb_frontend* fe, int reg, int data) | ||
93 | { | ||
94 | struct tda10021_state* state = fe->demodulator_priv; | ||
95 | |||
96 | return tda10021_writereg(state, reg, data); | ||
97 | } | ||
98 | EXPORT_SYMBOL(tda10021_write_byte); | ||
99 | |||
93 | static u8 tda10021_readreg (struct tda10021_state* state, u8 reg) | 100 | static u8 tda10021_readreg (struct tda10021_state* state, u8 reg) |
94 | { | 101 | { |
95 | u8 b0 [] = { reg }; | 102 | u8 b0 [] = { reg }; |
@@ -225,13 +232,6 @@ static int tda10021_init (struct dvb_frontend *fe) | |||
225 | 232 | ||
226 | //Activate PLL | 233 | //Activate PLL |
227 | tda10021_writereg(state, 0x2a, tda10021_inittab[0x2a] & 0xef); | 234 | tda10021_writereg(state, 0x2a, tda10021_inittab[0x2a] & 0xef); |
228 | |||
229 | if (state->config->pll_init) { | ||
230 | lock_tuner(state); | ||
231 | state->config->pll_init(fe); | ||
232 | unlock_tuner(state); | ||
233 | } | ||
234 | |||
235 | return 0; | 235 | return 0; |
236 | } | 236 | } |
237 | 237 | ||
@@ -259,9 +259,10 @@ static int tda10021_set_parameters (struct dvb_frontend *fe, | |||
259 | 259 | ||
260 | //printk("tda10021: set frequency to %d qam=%d symrate=%d\n", p->frequency,qam,p->u.qam.symbol_rate); | 260 | //printk("tda10021: set frequency to %d qam=%d symrate=%d\n", p->frequency,qam,p->u.qam.symbol_rate); |
261 | 261 | ||
262 | lock_tuner(state); | 262 | if (fe->ops.tuner_ops.set_params) { |
263 | state->config->pll_set(fe, p); | 263 | fe->ops.tuner_ops.set_params(fe, p); |
264 | unlock_tuner(state); | 264 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); |
265 | } | ||
265 | 266 | ||
266 | tda10021_set_symbolrate (state, p->u.qam.symbol_rate); | 267 | tda10021_set_symbolrate (state, p->u.qam.symbol_rate); |
267 | tda10021_writereg (state, 0x34, state->pwm); | 268 | tda10021_writereg (state, 0x34, state->pwm); |
@@ -376,6 +377,18 @@ static int tda10021_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_pa | |||
376 | return 0; | 377 | return 0; |
377 | } | 378 | } |
378 | 379 | ||
380 | static int tda10021_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) | ||
381 | { | ||
382 | struct tda10021_state* state = fe->demodulator_priv; | ||
383 | |||
384 | if (enable) { | ||
385 | lock_tuner(state); | ||
386 | } else { | ||
387 | unlock_tuner(state); | ||
388 | } | ||
389 | return 0; | ||
390 | } | ||
391 | |||
379 | static int tda10021_sleep(struct dvb_frontend* fe) | 392 | static int tda10021_sleep(struct dvb_frontend* fe) |
380 | { | 393 | { |
381 | struct tda10021_state* state = fe->demodulator_priv; | 394 | struct tda10021_state* state = fe->demodulator_priv; |
@@ -407,7 +420,6 @@ struct dvb_frontend* tda10021_attach(const struct tda10021_config* config, | |||
407 | /* setup the state */ | 420 | /* setup the state */ |
408 | state->config = config; | 421 | state->config = config; |
409 | state->i2c = i2c; | 422 | state->i2c = i2c; |
410 | memcpy(&state->ops, &tda10021_ops, sizeof(struct dvb_frontend_ops)); | ||
411 | state->pwm = pwm; | 423 | state->pwm = pwm; |
412 | state->reg0 = tda10021_inittab[0]; | 424 | state->reg0 = tda10021_inittab[0]; |
413 | 425 | ||
@@ -415,7 +427,7 @@ struct dvb_frontend* tda10021_attach(const struct tda10021_config* config, | |||
415 | if ((tda10021_readreg(state, 0x1a) & 0xf0) != 0x70) goto error; | 427 | if ((tda10021_readreg(state, 0x1a) & 0xf0) != 0x70) goto error; |
416 | 428 | ||
417 | /* create dvb_frontend */ | 429 | /* create dvb_frontend */ |
418 | state->frontend.ops = &state->ops; | 430 | memcpy(&state->frontend.ops, &tda10021_ops, sizeof(struct dvb_frontend_ops)); |
419 | state->frontend.demodulator_priv = state; | 431 | state->frontend.demodulator_priv = state; |
420 | return &state->frontend; | 432 | return &state->frontend; |
421 | 433 | ||
@@ -448,6 +460,7 @@ static struct dvb_frontend_ops tda10021_ops = { | |||
448 | 460 | ||
449 | .init = tda10021_init, | 461 | .init = tda10021_init, |
450 | .sleep = tda10021_sleep, | 462 | .sleep = tda10021_sleep, |
463 | .i2c_gate_ctrl = tda10021_i2c_gate_ctrl, | ||
451 | 464 | ||
452 | .set_frontend = tda10021_set_parameters, | 465 | .set_frontend = tda10021_set_parameters, |
453 | .get_frontend = tda10021_get_frontend, | 466 | .get_frontend = tda10021_get_frontend, |
diff --git a/drivers/media/dvb/frontends/tda10021.h b/drivers/media/dvb/frontends/tda10021.h index 53be939e8c55..b1df4259bee9 100644 --- a/drivers/media/dvb/frontends/tda10021.h +++ b/drivers/media/dvb/frontends/tda10021.h | |||
@@ -30,13 +30,11 @@ struct tda10021_config | |||
30 | { | 30 | { |
31 | /* the demodulator's i2c address */ | 31 | /* the demodulator's i2c address */ |
32 | u8 demod_address; | 32 | u8 demod_address; |
33 | |||
34 | /* PLL maintenance */ | ||
35 | int (*pll_init)(struct dvb_frontend* fe); | ||
36 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
37 | }; | 33 | }; |
38 | 34 | ||
39 | extern struct dvb_frontend* tda10021_attach(const struct tda10021_config* config, | 35 | extern struct dvb_frontend* tda10021_attach(const struct tda10021_config* config, |
40 | struct i2c_adapter* i2c, u8 pwm); | 36 | struct i2c_adapter* i2c, u8 pwm); |
41 | 37 | ||
38 | extern int tda10021_write_byte(struct dvb_frontend* fe, int reg, int data); | ||
39 | |||
42 | #endif // TDA10021_H | 40 | #endif // TDA10021_H |
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c index b83dafa4e12c..59a2ed614fca 100644 --- a/drivers/media/dvb/frontends/tda1004x.c +++ b/drivers/media/dvb/frontends/tda1004x.c | |||
@@ -47,7 +47,6 @@ enum tda1004x_demod { | |||
47 | 47 | ||
48 | struct tda1004x_state { | 48 | struct tda1004x_state { |
49 | struct i2c_adapter* i2c; | 49 | struct i2c_adapter* i2c; |
50 | struct dvb_frontend_ops ops; | ||
51 | const struct tda1004x_config* config; | 50 | const struct tda1004x_config* config; |
52 | struct dvb_frontend frontend; | 51 | struct dvb_frontend frontend; |
53 | 52 | ||
@@ -600,13 +599,6 @@ static int tda10045_init(struct dvb_frontend* fe) | |||
600 | 599 | ||
601 | tda1004x_write_mask(state, TDA1004X_CONFADC1, 0x10, 0); // wake up the ADC | 600 | tda1004x_write_mask(state, TDA1004X_CONFADC1, 0x10, 0); // wake up the ADC |
602 | 601 | ||
603 | // Init the PLL | ||
604 | if (state->config->pll_init) { | ||
605 | tda1004x_enable_tuner_i2c(state); | ||
606 | state->config->pll_init(fe); | ||
607 | tda1004x_disable_tuner_i2c(state); | ||
608 | } | ||
609 | |||
610 | // tda setup | 602 | // tda setup |
611 | tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer | 603 | tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer |
612 | tda1004x_write_mask(state, TDA1004X_AUTO, 8, 0); // select HP stream | 604 | tda1004x_write_mask(state, TDA1004X_AUTO, 8, 0); // select HP stream |
@@ -635,16 +627,6 @@ static int tda10046_init(struct dvb_frontend* fe) | |||
635 | return -EIO; | 627 | return -EIO; |
636 | } | 628 | } |
637 | 629 | ||
638 | // Init the tuner PLL | ||
639 | if (state->config->pll_init) { | ||
640 | tda1004x_enable_tuner_i2c(state); | ||
641 | if (state->config->pll_init(fe)) { | ||
642 | printk(KERN_ERR "tda1004x: pll init failed\n"); | ||
643 | return -EIO; | ||
644 | } | ||
645 | tda1004x_disable_tuner_i2c(state); | ||
646 | } | ||
647 | |||
648 | // tda setup | 630 | // tda setup |
649 | tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer | 631 | tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer |
650 | tda1004x_write_byteI(state, TDA1004X_AUTO, 0x87); // 100 ppm crystal, select HP stream | 632 | tda1004x_write_byteI(state, TDA1004X_AUTO, 0x87); // 100 ppm crystal, select HP stream |
@@ -712,12 +694,10 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, | |||
712 | } | 694 | } |
713 | 695 | ||
714 | // set frequency | 696 | // set frequency |
715 | tda1004x_enable_tuner_i2c(state); | 697 | if (fe->ops.tuner_ops.set_params) { |
716 | if (state->config->pll_set(fe, fe_params)) { | 698 | fe->ops.tuner_ops.set_params(fe, fe_params); |
717 | printk(KERN_ERR "tda1004x: pll set failed\n"); | 699 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); |
718 | return -EIO; | ||
719 | } | 700 | } |
720 | tda1004x_disable_tuner_i2c(state); | ||
721 | 701 | ||
722 | // Hardcoded to use auto as much as possible on the TDA10045 as it | 702 | // Hardcoded to use auto as much as possible on the TDA10045 as it |
723 | // is very unreliable if AUTO mode is _not_ used. | 703 | // is very unreliable if AUTO mode is _not_ used. |
@@ -1183,16 +1163,6 @@ static int tda1004x_sleep(struct dvb_frontend* fe) | |||
1183 | break; | 1163 | break; |
1184 | 1164 | ||
1185 | case TDA1004X_DEMOD_TDA10046: | 1165 | case TDA1004X_DEMOD_TDA10046: |
1186 | if (state->config->pll_sleep != NULL) { | ||
1187 | tda1004x_enable_tuner_i2c(state); | ||
1188 | state->config->pll_sleep(fe); | ||
1189 | if (state->config->if_freq != TDA10046_FREQ_052) { | ||
1190 | /* special hack for Philips EUROPA Based boards: | ||
1191 | * keep the I2c bridge open for tuner access in analog mode | ||
1192 | */ | ||
1193 | tda1004x_disable_tuner_i2c(state); | ||
1194 | } | ||
1195 | } | ||
1196 | /* set outputs to tristate */ | 1166 | /* set outputs to tristate */ |
1197 | tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0xff); | 1167 | tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0xff); |
1198 | tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1); | 1168 | tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1); |
@@ -1202,6 +1172,17 @@ static int tda1004x_sleep(struct dvb_frontend* fe) | |||
1202 | return 0; | 1172 | return 0; |
1203 | } | 1173 | } |
1204 | 1174 | ||
1175 | static int tda1004x_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) | ||
1176 | { | ||
1177 | struct tda1004x_state* state = fe->demodulator_priv; | ||
1178 | |||
1179 | if (enable) { | ||
1180 | return tda1004x_enable_tuner_i2c(state); | ||
1181 | } else { | ||
1182 | return tda1004x_disable_tuner_i2c(state); | ||
1183 | } | ||
1184 | } | ||
1185 | |||
1205 | static int tda1004x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) | 1186 | static int tda1004x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) |
1206 | { | 1187 | { |
1207 | fesettings->min_delay_ms = 800; | 1188 | fesettings->min_delay_ms = 800; |
@@ -1235,6 +1216,7 @@ static struct dvb_frontend_ops tda10045_ops = { | |||
1235 | 1216 | ||
1236 | .init = tda10045_init, | 1217 | .init = tda10045_init, |
1237 | .sleep = tda1004x_sleep, | 1218 | .sleep = tda1004x_sleep, |
1219 | .i2c_gate_ctrl = tda1004x_i2c_gate_ctrl, | ||
1238 | 1220 | ||
1239 | .set_frontend = tda1004x_set_fe, | 1221 | .set_frontend = tda1004x_set_fe, |
1240 | .get_frontend = tda1004x_get_fe, | 1222 | .get_frontend = tda1004x_get_fe, |
@@ -1260,7 +1242,6 @@ struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, | |||
1260 | /* setup the state */ | 1242 | /* setup the state */ |
1261 | state->config = config; | 1243 | state->config = config; |
1262 | state->i2c = i2c; | 1244 | state->i2c = i2c; |
1263 | memcpy(&state->ops, &tda10045_ops, sizeof(struct dvb_frontend_ops)); | ||
1264 | state->demod_type = TDA1004X_DEMOD_TDA10045; | 1245 | state->demod_type = TDA1004X_DEMOD_TDA10045; |
1265 | 1246 | ||
1266 | /* check if the demod is there */ | 1247 | /* check if the demod is there */ |
@@ -1270,7 +1251,7 @@ struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, | |||
1270 | } | 1251 | } |
1271 | 1252 | ||
1272 | /* create dvb_frontend */ | 1253 | /* create dvb_frontend */ |
1273 | state->frontend.ops = &state->ops; | 1254 | memcpy(&state->frontend.ops, &tda10045_ops, sizeof(struct dvb_frontend_ops)); |
1274 | state->frontend.demodulator_priv = state; | 1255 | state->frontend.demodulator_priv = state; |
1275 | return &state->frontend; | 1256 | return &state->frontend; |
1276 | } | 1257 | } |
@@ -1293,6 +1274,7 @@ static struct dvb_frontend_ops tda10046_ops = { | |||
1293 | 1274 | ||
1294 | .init = tda10046_init, | 1275 | .init = tda10046_init, |
1295 | .sleep = tda1004x_sleep, | 1276 | .sleep = tda1004x_sleep, |
1277 | .i2c_gate_ctrl = tda1004x_i2c_gate_ctrl, | ||
1296 | 1278 | ||
1297 | .set_frontend = tda1004x_set_fe, | 1279 | .set_frontend = tda1004x_set_fe, |
1298 | .get_frontend = tda1004x_get_fe, | 1280 | .get_frontend = tda1004x_get_fe, |
@@ -1318,7 +1300,6 @@ struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, | |||
1318 | /* setup the state */ | 1300 | /* setup the state */ |
1319 | state->config = config; | 1301 | state->config = config; |
1320 | state->i2c = i2c; | 1302 | state->i2c = i2c; |
1321 | memcpy(&state->ops, &tda10046_ops, sizeof(struct dvb_frontend_ops)); | ||
1322 | state->demod_type = TDA1004X_DEMOD_TDA10046; | 1303 | state->demod_type = TDA1004X_DEMOD_TDA10046; |
1323 | 1304 | ||
1324 | /* check if the demod is there */ | 1305 | /* check if the demod is there */ |
@@ -1328,7 +1309,7 @@ struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, | |||
1328 | } | 1309 | } |
1329 | 1310 | ||
1330 | /* create dvb_frontend */ | 1311 | /* create dvb_frontend */ |
1331 | state->frontend.ops = &state->ops; | 1312 | memcpy(&state->frontend.ops, &tda10046_ops, sizeof(struct dvb_frontend_ops)); |
1332 | state->frontend.demodulator_priv = state; | 1313 | state->frontend.demodulator_priv = state; |
1333 | return &state->frontend; | 1314 | return &state->frontend; |
1334 | } | 1315 | } |
diff --git a/drivers/media/dvb/frontends/tda1004x.h b/drivers/media/dvb/frontends/tda1004x.h index cc0c4af64067..b877b23ed734 100644 --- a/drivers/media/dvb/frontends/tda1004x.h +++ b/drivers/media/dvb/frontends/tda1004x.h | |||
@@ -66,11 +66,6 @@ struct tda1004x_config | |||
66 | /* AGC configuration */ | 66 | /* AGC configuration */ |
67 | enum tda10046_agc agc_config; | 67 | enum tda10046_agc agc_config; |
68 | 68 | ||
69 | /* PLL maintenance */ | ||
70 | int (*pll_init)(struct dvb_frontend* fe); | ||
71 | void (*pll_sleep)(struct dvb_frontend* fe); | ||
72 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
73 | |||
74 | /* request firmware for device */ | 69 | /* request firmware for device */ |
75 | /* set this to NULL if the card has a firmware EEPROM */ | 70 | /* set this to NULL if the card has a firmware EEPROM */ |
76 | int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); | 71 | int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); |
diff --git a/drivers/media/dvb/frontends/tda8083.c b/drivers/media/dvb/frontends/tda8083.c index 91baa9cedd79..3aa45ebbac3d 100644 --- a/drivers/media/dvb/frontends/tda8083.c +++ b/drivers/media/dvb/frontends/tda8083.c | |||
@@ -37,7 +37,6 @@ | |||
37 | 37 | ||
38 | struct tda8083_state { | 38 | struct tda8083_state { |
39 | struct i2c_adapter* i2c; | 39 | struct i2c_adapter* i2c; |
40 | struct dvb_frontend_ops ops; | ||
41 | /* configuration settings */ | 40 | /* configuration settings */ |
42 | const struct tda8083_config* config; | 41 | const struct tda8083_config* config; |
43 | struct dvb_frontend frontend; | 42 | struct dvb_frontend frontend; |
@@ -293,7 +292,11 @@ static int tda8083_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par | |||
293 | { | 292 | { |
294 | struct tda8083_state* state = fe->demodulator_priv; | 293 | struct tda8083_state* state = fe->demodulator_priv; |
295 | 294 | ||
296 | state->config->pll_set(fe, p); | 295 | if (fe->ops.tuner_ops.set_params) { |
296 | fe->ops.tuner_ops.set_params(fe, p); | ||
297 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); | ||
298 | } | ||
299 | |||
297 | tda8083_set_inversion (state, p->inversion); | 300 | tda8083_set_inversion (state, p->inversion); |
298 | tda8083_set_fec (state, p->u.qpsk.fec_inner); | 301 | tda8083_set_fec (state, p->u.qpsk.fec_inner); |
299 | tda8083_set_symbolrate (state, p->u.qpsk.symbol_rate); | 302 | tda8083_set_symbolrate (state, p->u.qpsk.symbol_rate); |
@@ -334,8 +337,6 @@ static int tda8083_init(struct dvb_frontend* fe) | |||
334 | for (i=0; i<44; i++) | 337 | for (i=0; i<44; i++) |
335 | tda8083_writereg (state, i, tda8083_init_tab[i]); | 338 | tda8083_writereg (state, i, tda8083_init_tab[i]); |
336 | 339 | ||
337 | if (state->config->pll_init) state->config->pll_init(fe); | ||
338 | |||
339 | tda8083_writereg (state, 0x00, 0x3c); | 340 | tda8083_writereg (state, 0x00, 0x3c); |
340 | tda8083_writereg (state, 0x00, 0x04); | 341 | tda8083_writereg (state, 0x00, 0x04); |
341 | 342 | ||
@@ -395,13 +396,12 @@ struct dvb_frontend* tda8083_attach(const struct tda8083_config* config, | |||
395 | /* setup the state */ | 396 | /* setup the state */ |
396 | state->config = config; | 397 | state->config = config; |
397 | state->i2c = i2c; | 398 | state->i2c = i2c; |
398 | memcpy(&state->ops, &tda8083_ops, sizeof(struct dvb_frontend_ops)); | ||
399 | 399 | ||
400 | /* check if the demod is there */ | 400 | /* check if the demod is there */ |
401 | if ((tda8083_readreg(state, 0x00)) != 0x05) goto error; | 401 | if ((tda8083_readreg(state, 0x00)) != 0x05) goto error; |
402 | 402 | ||
403 | /* create dvb_frontend */ | 403 | /* create dvb_frontend */ |
404 | state->frontend.ops = &state->ops; | 404 | memcpy(&state->frontend.ops, &tda8083_ops, sizeof(struct dvb_frontend_ops)); |
405 | state->frontend.demodulator_priv = state; | 405 | state->frontend.demodulator_priv = state; |
406 | return &state->frontend; | 406 | return &state->frontend; |
407 | 407 | ||
diff --git a/drivers/media/dvb/frontends/tda8083.h b/drivers/media/dvb/frontends/tda8083.h index 466663307bf1..e7a48f61ea2c 100644 --- a/drivers/media/dvb/frontends/tda8083.h +++ b/drivers/media/dvb/frontends/tda8083.h | |||
@@ -33,10 +33,6 @@ struct tda8083_config | |||
33 | { | 33 | { |
34 | /* the demodulator's i2c address */ | 34 | /* the demodulator's i2c address */ |
35 | u8 demod_address; | 35 | u8 demod_address; |
36 | |||
37 | /* PLL maintenance */ | ||
38 | int (*pll_init)(struct dvb_frontend* fe); | ||
39 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
40 | }; | 36 | }; |
41 | 37 | ||
42 | extern struct dvb_frontend* tda8083_attach(const struct tda8083_config* config, | 38 | extern struct dvb_frontend* tda8083_attach(const struct tda8083_config* config, |
diff --git a/drivers/media/dvb/frontends/ves1820.c b/drivers/media/dvb/frontends/ves1820.c index ad8647a3c85e..6bffe85c161c 100644 --- a/drivers/media/dvb/frontends/ves1820.c +++ b/drivers/media/dvb/frontends/ves1820.c | |||
@@ -35,7 +35,6 @@ | |||
35 | 35 | ||
36 | struct ves1820_state { | 36 | struct ves1820_state { |
37 | struct i2c_adapter* i2c; | 37 | struct i2c_adapter* i2c; |
38 | struct dvb_frontend_ops ops; | ||
39 | /* configuration settings */ | 38 | /* configuration settings */ |
40 | const struct ves1820_config* config; | 39 | const struct ves1820_config* config; |
41 | struct dvb_frontend frontend; | 40 | struct dvb_frontend frontend; |
@@ -204,9 +203,6 @@ static int ves1820_init(struct dvb_frontend* fe) | |||
204 | 203 | ||
205 | ves1820_writereg(state, 0x34, state->pwm); | 204 | ves1820_writereg(state, 0x34, state->pwm); |
206 | 205 | ||
207 | if (state->config->pll_init) | ||
208 | state->config->pll_init(fe); | ||
209 | |||
210 | return 0; | 206 | return 0; |
211 | } | 207 | } |
212 | 208 | ||
@@ -223,7 +219,11 @@ static int ves1820_set_parameters(struct dvb_frontend* fe, struct dvb_frontend_p | |||
223 | if (real_qam < 0 || real_qam > 4) | 219 | if (real_qam < 0 || real_qam > 4) |
224 | return -EINVAL; | 220 | return -EINVAL; |
225 | 221 | ||
226 | state->config->pll_set(fe, p); | 222 | if (fe->ops.tuner_ops.set_params) { |
223 | fe->ops.tuner_ops.set_params(fe, p); | ||
224 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); | ||
225 | } | ||
226 | |||
227 | ves1820_set_symbolrate(state, p->u.qam.symbol_rate); | 227 | ves1820_set_symbolrate(state, p->u.qam.symbol_rate); |
228 | ves1820_writereg(state, 0x34, state->pwm); | 228 | ves1820_writereg(state, 0x34, state->pwm); |
229 | 229 | ||
@@ -380,7 +380,6 @@ struct dvb_frontend* ves1820_attach(const struct ves1820_config* config, | |||
380 | goto error; | 380 | goto error; |
381 | 381 | ||
382 | /* setup the state */ | 382 | /* setup the state */ |
383 | memcpy(&state->ops, &ves1820_ops, sizeof(struct dvb_frontend_ops)); | ||
384 | state->reg0 = ves1820_inittab[0]; | 383 | state->reg0 = ves1820_inittab[0]; |
385 | state->config = config; | 384 | state->config = config; |
386 | state->i2c = i2c; | 385 | state->i2c = i2c; |
@@ -393,12 +392,12 @@ struct dvb_frontend* ves1820_attach(const struct ves1820_config* config, | |||
393 | if (verbose) | 392 | if (verbose) |
394 | printk("ves1820: pwm=0x%02x\n", state->pwm); | 393 | printk("ves1820: pwm=0x%02x\n", state->pwm); |
395 | 394 | ||
396 | state->ops.info.symbol_rate_min = (state->config->xin / 2) / 64; /* SACLK/64 == (XIN/2)/64 */ | ||
397 | state->ops.info.symbol_rate_max = (state->config->xin / 2) / 4; /* SACLK/4 */ | ||
398 | |||
399 | /* create dvb_frontend */ | 395 | /* create dvb_frontend */ |
400 | state->frontend.ops = &state->ops; | 396 | memcpy(&state->frontend.ops, &ves1820_ops, sizeof(struct dvb_frontend_ops)); |
397 | state->frontend.ops.info.symbol_rate_min = (state->config->xin / 2) / 64; /* SACLK/64 == (XIN/2)/64 */ | ||
398 | state->frontend.ops.info.symbol_rate_max = (state->config->xin / 2) / 4; /* SACLK/4 */ | ||
401 | state->frontend.demodulator_priv = state; | 399 | state->frontend.demodulator_priv = state; |
400 | |||
402 | return &state->frontend; | 401 | return &state->frontend; |
403 | 402 | ||
404 | error: | 403 | error: |
diff --git a/drivers/media/dvb/frontends/ves1820.h b/drivers/media/dvb/frontends/ves1820.h index 355f130b1be8..520f09522fbb 100644 --- a/drivers/media/dvb/frontends/ves1820.h +++ b/drivers/media/dvb/frontends/ves1820.h | |||
@@ -39,10 +39,6 @@ struct ves1820_config | |||
39 | 39 | ||
40 | /* SELAGC control */ | 40 | /* SELAGC control */ |
41 | u8 selagc:1; | 41 | u8 selagc:1; |
42 | |||
43 | /* PLL maintenance */ | ||
44 | int (*pll_init)(struct dvb_frontend* fe); | ||
45 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
46 | }; | 42 | }; |
47 | 43 | ||
48 | extern struct dvb_frontend* ves1820_attach(const struct ves1820_config* config, | 44 | extern struct dvb_frontend* ves1820_attach(const struct ves1820_config* config, |
diff --git a/drivers/media/dvb/frontends/ves1x93.c b/drivers/media/dvb/frontends/ves1x93.c index 821df8e839d0..54d7b07571b8 100644 --- a/drivers/media/dvb/frontends/ves1x93.c +++ b/drivers/media/dvb/frontends/ves1x93.c | |||
@@ -36,7 +36,6 @@ | |||
36 | 36 | ||
37 | struct ves1x93_state { | 37 | struct ves1x93_state { |
38 | struct i2c_adapter* i2c; | 38 | struct i2c_adapter* i2c; |
39 | struct dvb_frontend_ops ops; | ||
40 | /* configuration settings */ | 39 | /* configuration settings */ |
41 | const struct ves1x93_config* config; | 40 | const struct ves1x93_config* config; |
42 | struct dvb_frontend frontend; | 41 | struct dvb_frontend frontend; |
@@ -278,12 +277,6 @@ static int ves1x93_init (struct dvb_frontend* fe) | |||
278 | } | 277 | } |
279 | } | 278 | } |
280 | 279 | ||
281 | if (state->config->pll_init) { | ||
282 | ves1x93_writereg(state, 0x00, 0x11); | ||
283 | state->config->pll_init(fe); | ||
284 | ves1x93_writereg(state, 0x00, 0x01); | ||
285 | } | ||
286 | |||
287 | return 0; | 280 | return 0; |
288 | } | 281 | } |
289 | 282 | ||
@@ -395,9 +388,10 @@ static int ves1x93_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par | |||
395 | { | 388 | { |
396 | struct ves1x93_state* state = fe->demodulator_priv; | 389 | struct ves1x93_state* state = fe->demodulator_priv; |
397 | 390 | ||
398 | ves1x93_writereg(state, 0x00, 0x11); | 391 | if (fe->ops.tuner_ops.set_params) { |
399 | state->config->pll_set(fe, p); | 392 | fe->ops.tuner_ops.set_params(fe, p); |
400 | ves1x93_writereg(state, 0x00, 0x01); | 393 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); |
394 | } | ||
401 | ves1x93_set_inversion (state, p->inversion); | 395 | ves1x93_set_inversion (state, p->inversion); |
402 | ves1x93_set_fec (state, p->u.qpsk.fec_inner); | 396 | ves1x93_set_fec (state, p->u.qpsk.fec_inner); |
403 | ves1x93_set_symbolrate (state, p->u.qpsk.symbol_rate); | 397 | ves1x93_set_symbolrate (state, p->u.qpsk.symbol_rate); |
@@ -442,6 +436,17 @@ static void ves1x93_release(struct dvb_frontend* fe) | |||
442 | kfree(state); | 436 | kfree(state); |
443 | } | 437 | } |
444 | 438 | ||
439 | static int ves1x93_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) | ||
440 | { | ||
441 | struct ves1x93_state* state = fe->demodulator_priv; | ||
442 | |||
443 | if (enable) { | ||
444 | return ves1x93_writereg(state, 0x00, 0x11); | ||
445 | } else { | ||
446 | return ves1x93_writereg(state, 0x00, 0x01); | ||
447 | } | ||
448 | } | ||
449 | |||
445 | static struct dvb_frontend_ops ves1x93_ops; | 450 | static struct dvb_frontend_ops ves1x93_ops; |
446 | 451 | ||
447 | struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, | 452 | struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, |
@@ -457,7 +462,6 @@ struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, | |||
457 | /* setup the state */ | 462 | /* setup the state */ |
458 | state->config = config; | 463 | state->config = config; |
459 | state->i2c = i2c; | 464 | state->i2c = i2c; |
460 | memcpy(&state->ops, &ves1x93_ops, sizeof(struct dvb_frontend_ops)); | ||
461 | state->inversion = INVERSION_OFF; | 465 | state->inversion = INVERSION_OFF; |
462 | 466 | ||
463 | /* check if the demod is there + identify it */ | 467 | /* check if the demod is there + identify it */ |
@@ -492,7 +496,7 @@ struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, | |||
492 | } | 496 | } |
493 | 497 | ||
494 | /* create dvb_frontend */ | 498 | /* create dvb_frontend */ |
495 | state->frontend.ops = &state->ops; | 499 | memcpy(&state->frontend.ops, &ves1x93_ops, sizeof(struct dvb_frontend_ops)); |
496 | state->frontend.demodulator_priv = state; | 500 | state->frontend.demodulator_priv = state; |
497 | return &state->frontend; | 501 | return &state->frontend; |
498 | 502 | ||
@@ -523,6 +527,7 @@ static struct dvb_frontend_ops ves1x93_ops = { | |||
523 | 527 | ||
524 | .init = ves1x93_init, | 528 | .init = ves1x93_init, |
525 | .sleep = ves1x93_sleep, | 529 | .sleep = ves1x93_sleep, |
530 | .i2c_gate_ctrl = ves1x93_i2c_gate_ctrl, | ||
526 | 531 | ||
527 | .set_frontend = ves1x93_set_frontend, | 532 | .set_frontend = ves1x93_set_frontend, |
528 | .get_frontend = ves1x93_get_frontend, | 533 | .get_frontend = ves1x93_get_frontend, |
diff --git a/drivers/media/dvb/frontends/ves1x93.h b/drivers/media/dvb/frontends/ves1x93.h index 1627e37c57a4..ba88ae0855c9 100644 --- a/drivers/media/dvb/frontends/ves1x93.h +++ b/drivers/media/dvb/frontends/ves1x93.h | |||
@@ -38,10 +38,6 @@ struct ves1x93_config | |||
38 | 38 | ||
39 | /* should PWM be inverted? */ | 39 | /* should PWM be inverted? */ |
40 | u8 invert_pwm:1; | 40 | u8 invert_pwm:1; |
41 | |||
42 | /* PLL maintenance */ | ||
43 | int (*pll_init)(struct dvb_frontend* fe); | ||
44 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
45 | }; | 41 | }; |
46 | 42 | ||
47 | extern struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, | 43 | extern struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, |
diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c index d7d9f59d76d2..2b95e8b6cd39 100644 --- a/drivers/media/dvb/frontends/zl10353.c +++ b/drivers/media/dvb/frontends/zl10353.c | |||
@@ -34,7 +34,6 @@ | |||
34 | struct zl10353_state { | 34 | struct zl10353_state { |
35 | struct i2c_adapter *i2c; | 35 | struct i2c_adapter *i2c; |
36 | struct dvb_frontend frontend; | 36 | struct dvb_frontend frontend; |
37 | struct dvb_frontend_ops ops; | ||
38 | 37 | ||
39 | struct zl10353_config config; | 38 | struct zl10353_config config; |
40 | }; | 39 | }; |
@@ -126,6 +125,7 @@ static int zl10353_set_parameters(struct dvb_frontend *fe, | |||
126 | struct dvb_frontend_parameters *param) | 125 | struct dvb_frontend_parameters *param) |
127 | { | 126 | { |
128 | struct zl10353_state *state = fe->demodulator_priv; | 127 | struct zl10353_state *state = fe->demodulator_priv; |
128 | |||
129 | u8 pllbuf[6] = { 0x67 }; | 129 | u8 pllbuf[6] = { 0x67 }; |
130 | 130 | ||
131 | /* These settings set "auto-everything" and start the FSM. */ | 131 | /* These settings set "auto-everything" and start the FSM. */ |
@@ -142,7 +142,30 @@ static int zl10353_set_parameters(struct dvb_frontend *fe, | |||
142 | zl10353_single_write(fe, 0x66, 0xE9); | 142 | zl10353_single_write(fe, 0x66, 0xE9); |
143 | zl10353_single_write(fe, 0x62, 0x0A); | 143 | zl10353_single_write(fe, 0x62, 0x0A); |
144 | 144 | ||
145 | state->config.pll_set(fe, param, pllbuf + 1); | 145 | // if there is no attached secondary tuner, we call set_params to program |
146 | // a potential tuner attached somewhere else | ||
147 | if (state->config.no_tuner) { | ||
148 | if (fe->ops.tuner_ops.set_params) { | ||
149 | fe->ops.tuner_ops.set_params(fe, param); | ||
150 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); | ||
151 | } | ||
152 | } | ||
153 | |||
154 | // if pllbuf is defined, retrieve the settings | ||
155 | if (fe->ops.tuner_ops.calc_regs) { | ||
156 | fe->ops.tuner_ops.calc_regs(fe, param, pllbuf+1, 5); | ||
157 | pllbuf[1] <<= 1; | ||
158 | } else { | ||
159 | // fake pllbuf settings | ||
160 | pllbuf[1] = 0x61 << 1; | ||
161 | pllbuf[2] = 0; | ||
162 | pllbuf[3] = 0; | ||
163 | pllbuf[3] = 0; | ||
164 | pllbuf[4] = 0; | ||
165 | } | ||
166 | |||
167 | // there is no call to _just_ start decoding, so we send the pllbuf anyway | ||
168 | // even if there isn't a PLL attached to the secondary bus | ||
146 | zl10353_write(fe, pllbuf, sizeof(pllbuf)); | 169 | zl10353_write(fe, pllbuf, sizeof(pllbuf)); |
147 | 170 | ||
148 | zl10353_single_write(fe, 0x70, 0x01); | 171 | zl10353_single_write(fe, 0x70, 0x01); |
@@ -254,14 +277,13 @@ struct dvb_frontend *zl10353_attach(const struct zl10353_config *config, | |||
254 | /* setup the state */ | 277 | /* setup the state */ |
255 | state->i2c = i2c; | 278 | state->i2c = i2c; |
256 | memcpy(&state->config, config, sizeof(struct zl10353_config)); | 279 | memcpy(&state->config, config, sizeof(struct zl10353_config)); |
257 | memcpy(&state->ops, &zl10353_ops, sizeof(struct dvb_frontend_ops)); | ||
258 | 280 | ||
259 | /* check if the demod is there */ | 281 | /* check if the demod is there */ |
260 | if (zl10353_read_register(state, CHIP_ID) != ID_ZL10353) | 282 | if (zl10353_read_register(state, CHIP_ID) != ID_ZL10353) |
261 | goto error; | 283 | goto error; |
262 | 284 | ||
263 | /* create dvb_frontend */ | 285 | /* create dvb_frontend */ |
264 | state->frontend.ops = &state->ops; | 286 | memcpy(&state->frontend.ops, &zl10353_ops, sizeof(struct dvb_frontend_ops)); |
265 | state->frontend.demodulator_priv = state; | 287 | state->frontend.demodulator_priv = state; |
266 | 288 | ||
267 | return &state->frontend; | 289 | return &state->frontend; |
diff --git a/drivers/media/dvb/frontends/zl10353.h b/drivers/media/dvb/frontends/zl10353.h index 5cc4ae718d8c..9770cb840cfc 100644 --- a/drivers/media/dvb/frontends/zl10353.h +++ b/drivers/media/dvb/frontends/zl10353.h | |||
@@ -29,10 +29,8 @@ struct zl10353_config | |||
29 | /* demodulator's I2C address */ | 29 | /* demodulator's I2C address */ |
30 | u8 demod_address; | 30 | u8 demod_address; |
31 | 31 | ||
32 | /* function which configures the PLL buffer (for secondary I2C | 32 | /* set if no pll is connected to the secondary i2c bus */ |
33 | * connected tuner) or tunes the PLL (for direct connected tuner) */ | 33 | int no_tuner; |
34 | int (*pll_set)(struct dvb_frontend *fe, | ||
35 | struct dvb_frontend_parameters *params, u8 *pllbuf); | ||
36 | }; | 34 | }; |
37 | 35 | ||
38 | extern struct dvb_frontend* zl10353_attach(const struct zl10353_config *config, | 36 | extern struct dvb_frontend* zl10353_attach(const struct zl10353_config *config, |
diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c index 1c5316e209ef..acabea0793b6 100644 --- a/drivers/media/dvb/pluto2/pluto2.c +++ b/drivers/media/dvb/pluto2/pluto2.c | |||
@@ -424,8 +424,8 @@ static inline u32 divide(u32 numerator, u32 denominator) | |||
424 | } | 424 | } |
425 | 425 | ||
426 | /* LG Innotek TDTE-E001P (Infineon TUA6034) */ | 426 | /* LG Innotek TDTE-E001P (Infineon TUA6034) */ |
427 | static int lg_tdtpe001p_pll_set(struct dvb_frontend *fe, | 427 | static int lg_tdtpe001p_tuner_set_params(struct dvb_frontend *fe, |
428 | struct dvb_frontend_parameters *p) | 428 | struct dvb_frontend_parameters *p) |
429 | { | 429 | { |
430 | struct pluto *pluto = frontend_to_pluto(fe); | 430 | struct pluto *pluto = frontend_to_pluto(fe); |
431 | struct i2c_msg msg; | 431 | struct i2c_msg msg; |
@@ -473,6 +473,8 @@ static int lg_tdtpe001p_pll_set(struct dvb_frontend *fe, | |||
473 | msg.buf = buf; | 473 | msg.buf = buf; |
474 | msg.len = sizeof(buf); | 474 | msg.len = sizeof(buf); |
475 | 475 | ||
476 | if (fe->ops.i2c_gate_ctrl) | ||
477 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
476 | ret = i2c_transfer(&pluto->i2c_adap, &msg, 1); | 478 | ret = i2c_transfer(&pluto->i2c_adap, &msg, 1); |
477 | if (ret < 0) | 479 | if (ret < 0) |
478 | return ret; | 480 | return ret; |
@@ -497,8 +499,6 @@ static struct tda1004x_config pluto2_fe_config __devinitdata = { | |||
497 | .xtal_freq = TDA10046_XTAL_16M, | 499 | .xtal_freq = TDA10046_XTAL_16M, |
498 | .agc_config = TDA10046_AGC_DEFAULT, | 500 | .agc_config = TDA10046_AGC_DEFAULT, |
499 | .if_freq = TDA10046_FREQ_3617, | 501 | .if_freq = TDA10046_FREQ_3617, |
500 | .pll_set = lg_tdtpe001p_pll_set, | ||
501 | .pll_sleep = NULL, | ||
502 | .request_firmware = pluto2_request_firmware, | 502 | .request_firmware = pluto2_request_firmware, |
503 | }; | 503 | }; |
504 | 504 | ||
@@ -511,11 +511,12 @@ static int __devinit frontend_init(struct pluto *pluto) | |||
511 | dev_err(&pluto->pdev->dev, "could not attach frontend\n"); | 511 | dev_err(&pluto->pdev->dev, "could not attach frontend\n"); |
512 | return -ENODEV; | 512 | return -ENODEV; |
513 | } | 513 | } |
514 | pluto->fe->ops.tuner_ops.set_params = lg_tdtpe001p_tuner_set_params; | ||
514 | 515 | ||
515 | ret = dvb_register_frontend(&pluto->dvb_adapter, pluto->fe); | 516 | ret = dvb_register_frontend(&pluto->dvb_adapter, pluto->fe); |
516 | if (ret < 0) { | 517 | if (ret < 0) { |
517 | if (pluto->fe->ops->release) | 518 | if (pluto->fe->ops.release) |
518 | pluto->fe->ops->release(pluto->fe); | 519 | pluto->fe->ops.release(pluto->fe); |
519 | return ret; | 520 | return ret; |
520 | } | 521 | } |
521 | 522 | ||
@@ -647,7 +648,7 @@ static int __devinit pluto2_probe(struct pci_dev *pdev, | |||
647 | goto err_pluto_hw_exit; | 648 | goto err_pluto_hw_exit; |
648 | 649 | ||
649 | /* dvb */ | 650 | /* dvb */ |
650 | ret = dvb_register_adapter(&pluto->dvb_adapter, DRIVER_NAME, THIS_MODULE); | 651 | ret = dvb_register_adapter(&pluto->dvb_adapter, DRIVER_NAME, THIS_MODULE, &pdev->dev); |
651 | if (ret < 0) | 652 | if (ret < 0) |
652 | goto err_i2c_bit_del_bus; | 653 | goto err_i2c_bit_del_bus; |
653 | 654 | ||
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig index b5ac7dfde52f..987881fa988c 100644 --- a/drivers/media/dvb/ttpci/Kconfig +++ b/drivers/media/dvb/ttpci/Kconfig | |||
@@ -10,6 +10,7 @@ config DVB_AV7110 | |||
10 | select DVB_SP8870 | 10 | select DVB_SP8870 |
11 | select DVB_STV0297 | 11 | select DVB_STV0297 |
12 | select DVB_L64781 | 12 | select DVB_L64781 |
13 | select DVB_LNBP21 | ||
13 | help | 14 | help |
14 | Support for SAA7146 and AV7110 based DVB cards as produced | 15 | Support for SAA7146 and AV7110 based DVB cards as produced |
15 | by Fujitsu-Siemens, Technotrend, Hauppauge and others. | 16 | by Fujitsu-Siemens, Technotrend, Hauppauge and others. |
@@ -67,6 +68,7 @@ config DVB_BUDGET | |||
67 | select DVB_TDA8083 | 68 | select DVB_TDA8083 |
68 | select DVB_TDA10021 | 69 | select DVB_TDA10021 |
69 | select DVB_S5H1420 | 70 | select DVB_S5H1420 |
71 | select DVB_LNBP21 | ||
70 | help | 72 | help |
71 | Support for simple SAA7146 based DVB cards | 73 | Support for simple SAA7146 based DVB cards |
72 | (so called Budget- or Nova-PCI cards) without onboard | 74 | (so called Budget- or Nova-PCI cards) without onboard |
@@ -84,6 +86,7 @@ config DVB_BUDGET_CI | |||
84 | select DVB_STV0297 | 86 | select DVB_STV0297 |
85 | select DVB_STV0299 | 87 | select DVB_STV0299 |
86 | select DVB_TDA1004X | 88 | select DVB_TDA1004X |
89 | select DVB_LNBP21 | ||
87 | help | 90 | help |
88 | Support for simple SAA7146 based DVB cards | 91 | Support for simple SAA7146 based DVB cards |
89 | (so called Budget- or Nova-PCI cards) without onboard | 92 | (so called Budget- or Nova-PCI cards) without onboard |
diff --git a/drivers/media/dvb/ttpci/Makefile b/drivers/media/dvb/ttpci/Makefile index a690730ac39d..aa85ecdc6c80 100644 --- a/drivers/media/dvb/ttpci/Makefile +++ b/drivers/media/dvb/ttpci/Makefile | |||
@@ -15,9 +15,9 @@ EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ | |||
15 | 15 | ||
16 | hostprogs-y := fdump | 16 | hostprogs-y := fdump |
17 | 17 | ||
18 | ifdef CONFIG_DVB_AV7110_FIRMWARE | 18 | ifeq ($(CONFIG_DVB_AV7110_FIRMWARE),y) |
19 | $(obj)/av7110.o: $(obj)/fdump $(obj)/av7110_firm.h | 19 | $(obj)/av7110.o: $(obj)/av7110_firm.h |
20 | 20 | ||
21 | $(obj)/av7110_firm.h: | 21 | $(obj)/av7110_firm.h: $(obj)/fdump |
22 | $(obj)/fdump $(CONFIG_DVB_AV7110_FIRMWARE_FILE) dvb_ttpci_fw $@ | 22 | $(obj)/fdump $(CONFIG_DVB_AV7110_FIRMWARE_FILE) dvb_ttpci_fw $@ |
23 | endif | 23 | endif |
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index d028245c8eed..8832f80c05f7 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c | |||
@@ -1552,7 +1552,7 @@ static int get_firmware(struct av7110* av7110) | |||
1552 | #endif | 1552 | #endif |
1553 | 1553 | ||
1554 | 1554 | ||
1555 | static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 1555 | static int alps_bsrv2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) |
1556 | { | 1556 | { |
1557 | struct av7110* av7110 = (struct av7110*) fe->dvb->priv; | 1557 | struct av7110* av7110 = (struct av7110*) fe->dvb->priv; |
1558 | u8 pwr = 0; | 1558 | u8 pwr = 0; |
@@ -1575,6 +1575,8 @@ static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_param | |||
1575 | // NOTE: since we're using a prescaler of 2, we set the | 1575 | // NOTE: since we're using a prescaler of 2, we set the |
1576 | // divisor frequency to 62.5kHz and divide by 125 above | 1576 | // divisor frequency to 62.5kHz and divide by 125 above |
1577 | 1577 | ||
1578 | if (fe->ops.i2c_gate_ctrl) | ||
1579 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1578 | if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1) | 1580 | if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1) |
1579 | return -EIO; | 1581 | return -EIO; |
1580 | return 0; | 1582 | return 0; |
@@ -1584,10 +1586,9 @@ static struct ves1x93_config alps_bsrv2_config = { | |||
1584 | .demod_address = 0x08, | 1586 | .demod_address = 0x08, |
1585 | .xin = 90100000UL, | 1587 | .xin = 90100000UL, |
1586 | .invert_pwm = 0, | 1588 | .invert_pwm = 0, |
1587 | .pll_set = alps_bsrv2_pll_set, | ||
1588 | }; | 1589 | }; |
1589 | 1590 | ||
1590 | static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 1591 | static int alps_tdbe2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) |
1591 | { | 1592 | { |
1592 | struct av7110* av7110 = fe->dvb->priv; | 1593 | struct av7110* av7110 = fe->dvb->priv; |
1593 | u32 div; | 1594 | u32 div; |
@@ -1601,6 +1602,8 @@ static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_param | |||
1601 | data[2] = 0x85 | ((div >> 10) & 0x60); | 1602 | data[2] = 0x85 | ((div >> 10) & 0x60); |
1602 | data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81); | 1603 | data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81); |
1603 | 1604 | ||
1605 | if (fe->ops.i2c_gate_ctrl) | ||
1606 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1604 | if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) | 1607 | if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) |
1605 | return -EIO; | 1608 | return -EIO; |
1606 | return 0; | 1609 | return 0; |
@@ -1611,14 +1614,12 @@ static struct ves1820_config alps_tdbe2_config = { | |||
1611 | .xin = 57840000UL, | 1614 | .xin = 57840000UL, |
1612 | .invert = 1, | 1615 | .invert = 1, |
1613 | .selagc = VES1820_SELAGC_SIGNAMPERR, | 1616 | .selagc = VES1820_SELAGC_SIGNAMPERR, |
1614 | .pll_set = alps_tdbe2_pll_set, | ||
1615 | }; | 1617 | }; |
1616 | 1618 | ||
1617 | 1619 | ||
1618 | 1620 | ||
1619 | 1621 | ||
1620 | static int grundig_29504_451_pll_set(struct dvb_frontend* fe, | 1622 | static int grundig_29504_451_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) |
1621 | struct dvb_frontend_parameters* params) | ||
1622 | { | 1623 | { |
1623 | struct av7110* av7110 = fe->dvb->priv; | 1624 | struct av7110* av7110 = fe->dvb->priv; |
1624 | u32 div; | 1625 | u32 div; |
@@ -1631,6 +1632,8 @@ static int grundig_29504_451_pll_set(struct dvb_frontend* fe, | |||
1631 | data[2] = 0x8e; | 1632 | data[2] = 0x8e; |
1632 | data[3] = 0x00; | 1633 | data[3] = 0x00; |
1633 | 1634 | ||
1635 | if (fe->ops.i2c_gate_ctrl) | ||
1636 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1634 | if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) | 1637 | if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) |
1635 | return -EIO; | 1638 | return -EIO; |
1636 | return 0; | 1639 | return 0; |
@@ -1638,13 +1641,11 @@ static int grundig_29504_451_pll_set(struct dvb_frontend* fe, | |||
1638 | 1641 | ||
1639 | static struct tda8083_config grundig_29504_451_config = { | 1642 | static struct tda8083_config grundig_29504_451_config = { |
1640 | .demod_address = 0x68, | 1643 | .demod_address = 0x68, |
1641 | .pll_set = grundig_29504_451_pll_set, | ||
1642 | }; | 1644 | }; |
1643 | 1645 | ||
1644 | 1646 | ||
1645 | 1647 | ||
1646 | static int philips_cd1516_pll_set(struct dvb_frontend* fe, | 1648 | static int philips_cd1516_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) |
1647 | struct dvb_frontend_parameters* params) | ||
1648 | { | 1649 | { |
1649 | struct av7110* av7110 = fe->dvb->priv; | 1650 | struct av7110* av7110 = fe->dvb->priv; |
1650 | u32 div; | 1651 | u32 div; |
@@ -1659,6 +1660,8 @@ static int philips_cd1516_pll_set(struct dvb_frontend* fe, | |||
1659 | data[2] = 0x8e; | 1660 | data[2] = 0x8e; |
1660 | data[3] = (f < 174000000 ? 0xa1 : f < 470000000 ? 0x92 : 0x34); | 1661 | data[3] = (f < 174000000 ? 0xa1 : f < 470000000 ? 0x92 : 0x34); |
1661 | 1662 | ||
1663 | if (fe->ops.i2c_gate_ctrl) | ||
1664 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1662 | if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) | 1665 | if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) |
1663 | return -EIO; | 1666 | return -EIO; |
1664 | return 0; | 1667 | return 0; |
@@ -1669,12 +1672,11 @@ static struct ves1820_config philips_cd1516_config = { | |||
1669 | .xin = 57840000UL, | 1672 | .xin = 57840000UL, |
1670 | .invert = 1, | 1673 | .invert = 1, |
1671 | .selagc = VES1820_SELAGC_SIGNAMPERR, | 1674 | .selagc = VES1820_SELAGC_SIGNAMPERR, |
1672 | .pll_set = philips_cd1516_pll_set, | ||
1673 | }; | 1675 | }; |
1674 | 1676 | ||
1675 | 1677 | ||
1676 | 1678 | ||
1677 | static int alps_tdlb7_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 1679 | static int alps_tdlb7_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) |
1678 | { | 1680 | { |
1679 | struct av7110* av7110 = fe->dvb->priv; | 1681 | struct av7110* av7110 = fe->dvb->priv; |
1680 | u32 div, pwr; | 1682 | u32 div, pwr; |
@@ -1693,6 +1695,8 @@ static int alps_tdlb7_pll_set(struct dvb_frontend* fe, struct dvb_frontend_param | |||
1693 | data[2] = 0x85; | 1695 | data[2] = 0x85; |
1694 | data[3] = pwr << 6; | 1696 | data[3] = pwr << 6; |
1695 | 1697 | ||
1698 | if (fe->ops.i2c_gate_ctrl) | ||
1699 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1696 | if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) | 1700 | if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) |
1697 | return -EIO; | 1701 | return -EIO; |
1698 | return 0; | 1702 | return 0; |
@@ -1708,7 +1712,6 @@ static int alps_tdlb7_request_firmware(struct dvb_frontend* fe, const struct fir | |||
1708 | static struct sp8870_config alps_tdlb7_config = { | 1712 | static struct sp8870_config alps_tdlb7_config = { |
1709 | 1713 | ||
1710 | .demod_address = 0x71, | 1714 | .demod_address = 0x71, |
1711 | .pll_set = alps_tdlb7_pll_set, | ||
1712 | .request_firmware = alps_tdlb7_request_firmware, | 1715 | .request_firmware = alps_tdlb7_request_firmware, |
1713 | }; | 1716 | }; |
1714 | 1717 | ||
@@ -1806,7 +1809,7 @@ static u8 nexusca_stv0297_inittab[] = { | |||
1806 | 0xff, 0xff, | 1809 | 0xff, 0xff, |
1807 | }; | 1810 | }; |
1808 | 1811 | ||
1809 | static int nexusca_stv0297_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 1812 | static int nexusca_stv0297_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) |
1810 | { | 1813 | { |
1811 | struct av7110* av7110 = fe->dvb->priv; | 1814 | struct av7110* av7110 = fe->dvb->priv; |
1812 | u32 div; | 1815 | u32 div; |
@@ -1832,7 +1835,8 @@ static int nexusca_stv0297_pll_set(struct dvb_frontend* fe, struct dvb_frontend_ | |||
1832 | else | 1835 | else |
1833 | return -EINVAL; | 1836 | return -EINVAL; |
1834 | 1837 | ||
1835 | stv0297_enable_plli2c(fe); | 1838 | if (fe->ops.i2c_gate_ctrl) |
1839 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1836 | if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) { | 1840 | if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) { |
1837 | printk("nexusca: pll transfer failed!\n"); | 1841 | printk("nexusca: pll transfer failed!\n"); |
1838 | return -EIO; | 1842 | return -EIO; |
@@ -1840,8 +1844,8 @@ static int nexusca_stv0297_pll_set(struct dvb_frontend* fe, struct dvb_frontend_ | |||
1840 | 1844 | ||
1841 | // wait for PLL lock | 1845 | // wait for PLL lock |
1842 | for(i = 0; i < 20; i++) { | 1846 | for(i = 0; i < 20; i++) { |
1843 | 1847 | if (fe->ops.i2c_gate_ctrl) | |
1844 | stv0297_enable_plli2c(fe); | 1848 | fe->ops.i2c_gate_ctrl(fe, 1); |
1845 | if (i2c_transfer(&av7110->i2c_adap, &readmsg, 1) == 1) | 1849 | if (i2c_transfer(&av7110->i2c_adap, &readmsg, 1) == 1) |
1846 | if (data[0] & 0x40) break; | 1850 | if (data[0] & 0x40) break; |
1847 | msleep(10); | 1851 | msleep(10); |
@@ -1855,12 +1859,12 @@ static struct stv0297_config nexusca_stv0297_config = { | |||
1855 | .demod_address = 0x1C, | 1859 | .demod_address = 0x1C, |
1856 | .inittab = nexusca_stv0297_inittab, | 1860 | .inittab = nexusca_stv0297_inittab, |
1857 | .invert = 1, | 1861 | .invert = 1, |
1858 | .pll_set = nexusca_stv0297_pll_set, | 1862 | .stop_during_read = 1, |
1859 | }; | 1863 | }; |
1860 | 1864 | ||
1861 | 1865 | ||
1862 | 1866 | ||
1863 | static int grundig_29504_401_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 1867 | static int grundig_29504_401_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) |
1864 | { | 1868 | { |
1865 | struct av7110* av7110 = (struct av7110*) fe->dvb->priv; | 1869 | struct av7110* av7110 = (struct av7110*) fe->dvb->priv; |
1866 | u32 div; | 1870 | u32 div; |
@@ -1887,13 +1891,14 @@ static int grundig_29504_401_pll_set(struct dvb_frontend* fe, struct dvb_fronten | |||
1887 | data[2] = ((div >> 10) & 0x60) | cfg; | 1891 | data[2] = ((div >> 10) & 0x60) | cfg; |
1888 | data[3] = (cpump << 6) | band_select; | 1892 | data[3] = (cpump << 6) | band_select; |
1889 | 1893 | ||
1894 | if (fe->ops.i2c_gate_ctrl) | ||
1895 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1890 | if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1) return -EIO; | 1896 | if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1) return -EIO; |
1891 | return 0; | 1897 | return 0; |
1892 | } | 1898 | } |
1893 | 1899 | ||
1894 | static struct l64781_config grundig_29504_401_config = { | 1900 | static struct l64781_config grundig_29504_401_config = { |
1895 | .demod_address = 0x55, | 1901 | .demod_address = 0x55, |
1896 | .pll_set = grundig_29504_401_pll_set, | ||
1897 | }; | 1902 | }; |
1898 | 1903 | ||
1899 | 1904 | ||
@@ -2079,6 +2084,9 @@ static int frontend_init(struct av7110 *av7110) | |||
2079 | case 0x0000: // Fujitsu/Siemens DVB-Cable (ves1820/Philips CD1516(??)) | 2084 | case 0x0000: // Fujitsu/Siemens DVB-Cable (ves1820/Philips CD1516(??)) |
2080 | av7110->fe = ves1820_attach(&philips_cd1516_config, | 2085 | av7110->fe = ves1820_attach(&philips_cd1516_config, |
2081 | &av7110->i2c_adap, read_pwm(av7110)); | 2086 | &av7110->i2c_adap, read_pwm(av7110)); |
2087 | if (av7110->fe) { | ||
2088 | av7110->fe->ops.tuner_ops.set_params = philips_cd1516_tuner_set_params; | ||
2089 | } | ||
2082 | break; | 2090 | break; |
2083 | } | 2091 | } |
2084 | 2092 | ||
@@ -2091,9 +2099,10 @@ static int frontend_init(struct av7110 *av7110) | |||
2091 | // try the ALPS BSRV2 first of all | 2099 | // try the ALPS BSRV2 first of all |
2092 | av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap); | 2100 | av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap); |
2093 | if (av7110->fe) { | 2101 | if (av7110->fe) { |
2094 | av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; | 2102 | av7110->fe->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params; |
2095 | av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; | 2103 | av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; |
2096 | av7110->fe->ops->set_tone = av7110_set_tone; | 2104 | av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst; |
2105 | av7110->fe->ops.set_tone = av7110_set_tone; | ||
2097 | av7110->recover = dvb_s_recover; | 2106 | av7110->recover = dvb_s_recover; |
2098 | break; | 2107 | break; |
2099 | } | 2108 | } |
@@ -2101,9 +2110,12 @@ static int frontend_init(struct av7110 *av7110) | |||
2101 | // try the ALPS BSRU6 now | 2110 | // try the ALPS BSRU6 now |
2102 | av7110->fe = stv0299_attach(&alps_bsru6_config, &av7110->i2c_adap); | 2111 | av7110->fe = stv0299_attach(&alps_bsru6_config, &av7110->i2c_adap); |
2103 | if (av7110->fe) { | 2112 | if (av7110->fe) { |
2104 | av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; | 2113 | av7110->fe->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; |
2105 | av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; | 2114 | av7110->fe->tuner_priv = &av7110->i2c_adap; |
2106 | av7110->fe->ops->set_tone = av7110_set_tone; | 2115 | |
2116 | av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; | ||
2117 | av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst; | ||
2118 | av7110->fe->ops.set_tone = av7110_set_tone; | ||
2107 | av7110->recover = dvb_s_recover; | 2119 | av7110->recover = dvb_s_recover; |
2108 | break; | 2120 | break; |
2109 | } | 2121 | } |
@@ -2111,9 +2123,10 @@ static int frontend_init(struct av7110 *av7110) | |||
2111 | // Try the grundig 29504-451 | 2123 | // Try the grundig 29504-451 |
2112 | av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap); | 2124 | av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap); |
2113 | if (av7110->fe) { | 2125 | if (av7110->fe) { |
2114 | av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; | 2126 | av7110->fe->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params; |
2115 | av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; | 2127 | av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; |
2116 | av7110->fe->ops->set_tone = av7110_set_tone; | 2128 | av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst; |
2129 | av7110->fe->ops.set_tone = av7110_set_tone; | ||
2117 | av7110->recover = dvb_s_recover; | 2130 | av7110->recover = dvb_s_recover; |
2118 | break; | 2131 | break; |
2119 | } | 2132 | } |
@@ -2124,11 +2137,17 @@ static int frontend_init(struct av7110 *av7110) | |||
2124 | /* Siemens DVB-C (full-length card) VES1820/Philips CD1516 */ | 2137 | /* Siemens DVB-C (full-length card) VES1820/Philips CD1516 */ |
2125 | av7110->fe = ves1820_attach(&philips_cd1516_config, &av7110->i2c_adap, | 2138 | av7110->fe = ves1820_attach(&philips_cd1516_config, &av7110->i2c_adap, |
2126 | read_pwm(av7110)); | 2139 | read_pwm(av7110)); |
2140 | if (av7110->fe) { | ||
2141 | av7110->fe->ops.tuner_ops.set_params = philips_cd1516_tuner_set_params; | ||
2142 | } | ||
2127 | break; | 2143 | break; |
2128 | case 0x0003: | 2144 | case 0x0003: |
2129 | /* Hauppauge DVB-C 2.1 VES1820/ALPS TDBE2 */ | 2145 | /* Hauppauge DVB-C 2.1 VES1820/ALPS TDBE2 */ |
2130 | av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, | 2146 | av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, |
2131 | read_pwm(av7110)); | 2147 | read_pwm(av7110)); |
2148 | if (av7110->fe) { | ||
2149 | av7110->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params; | ||
2150 | } | ||
2132 | break; | 2151 | break; |
2133 | } | 2152 | } |
2134 | break; | 2153 | break; |
@@ -2137,20 +2156,27 @@ static int frontend_init(struct av7110 *av7110) | |||
2137 | 2156 | ||
2138 | // ALPS TDLB7 | 2157 | // ALPS TDLB7 |
2139 | av7110->fe = sp8870_attach(&alps_tdlb7_config, &av7110->i2c_adap); | 2158 | av7110->fe = sp8870_attach(&alps_tdlb7_config, &av7110->i2c_adap); |
2159 | if (av7110->fe) { | ||
2160 | av7110->fe->ops.tuner_ops.set_params = alps_tdlb7_tuner_set_params; | ||
2161 | } | ||
2140 | break; | 2162 | break; |
2141 | 2163 | ||
2142 | case 0x0002: // Hauppauge/TT DVB-C premium rev2.X | 2164 | case 0x0002: // Hauppauge/TT DVB-C premium rev2.X |
2143 | 2165 | ||
2144 | av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110)); | 2166 | av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110)); |
2167 | if (av7110->fe) { | ||
2168 | av7110->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params; | ||
2169 | } | ||
2145 | break; | 2170 | break; |
2146 | 2171 | ||
2147 | case 0x0004: // Galaxis DVB-S rev1.3 | 2172 | case 0x0004: // Galaxis DVB-S rev1.3 |
2148 | /* ALPS BSRV2 */ | 2173 | /* ALPS BSRV2 */ |
2149 | av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap); | 2174 | av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap); |
2150 | if (av7110->fe) { | 2175 | if (av7110->fe) { |
2151 | av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; | 2176 | av7110->fe->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params; |
2152 | av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; | 2177 | av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; |
2153 | av7110->fe->ops->set_tone = av7110_set_tone; | 2178 | av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst; |
2179 | av7110->fe->ops.set_tone = av7110_set_tone; | ||
2154 | av7110->recover = dvb_s_recover; | 2180 | av7110->recover = dvb_s_recover; |
2155 | } | 2181 | } |
2156 | break; | 2182 | break; |
@@ -2159,9 +2185,10 @@ static int frontend_init(struct av7110 *av7110) | |||
2159 | /* Grundig 29504-451 */ | 2185 | /* Grundig 29504-451 */ |
2160 | av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap); | 2186 | av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap); |
2161 | if (av7110->fe) { | 2187 | if (av7110->fe) { |
2162 | av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; | 2188 | av7110->fe->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params; |
2163 | av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; | 2189 | av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; |
2164 | av7110->fe->ops->set_tone = av7110_set_tone; | 2190 | av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst; |
2191 | av7110->fe->ops.set_tone = av7110_set_tone; | ||
2165 | av7110->recover = dvb_s_recover; | 2192 | av7110->recover = dvb_s_recover; |
2166 | } | 2193 | } |
2167 | break; | 2194 | break; |
@@ -2169,12 +2196,17 @@ static int frontend_init(struct av7110 *av7110) | |||
2169 | case 0x0008: // Hauppauge/TT DVB-T | 2196 | case 0x0008: // Hauppauge/TT DVB-T |
2170 | 2197 | ||
2171 | av7110->fe = l64781_attach(&grundig_29504_401_config, &av7110->i2c_adap); | 2198 | av7110->fe = l64781_attach(&grundig_29504_401_config, &av7110->i2c_adap); |
2199 | if (av7110->fe) { | ||
2200 | av7110->fe->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params; | ||
2201 | } | ||
2172 | break; | 2202 | break; |
2173 | 2203 | ||
2174 | case 0x000A: // Hauppauge/TT Nexus-CA rev1.X | 2204 | case 0x000A: // Hauppauge/TT Nexus-CA rev1.X |
2175 | 2205 | ||
2176 | av7110->fe = stv0297_attach(&nexusca_stv0297_config, &av7110->i2c_adap); | 2206 | av7110->fe = stv0297_attach(&nexusca_stv0297_config, &av7110->i2c_adap); |
2177 | if (av7110->fe) { | 2207 | if (av7110->fe) { |
2208 | av7110->fe->ops.tuner_ops.set_params = nexusca_stv0297_tuner_set_params; | ||
2209 | |||
2178 | /* set TDA9819 into DVB mode */ | 2210 | /* set TDA9819 into DVB mode */ |
2179 | saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9198 pin9(STD) | 2211 | saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9198 pin9(STD) |
2180 | saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF) | 2212 | saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF) |
@@ -2189,13 +2221,16 @@ static int frontend_init(struct av7110 *av7110) | |||
2189 | /* ALPS BSBE1 */ | 2221 | /* ALPS BSBE1 */ |
2190 | av7110->fe = stv0299_attach(&alps_bsbe1_config, &av7110->i2c_adap); | 2222 | av7110->fe = stv0299_attach(&alps_bsbe1_config, &av7110->i2c_adap); |
2191 | if (av7110->fe) { | 2223 | if (av7110->fe) { |
2192 | if (lnbp21_init(av7110->fe, &av7110->i2c_adap, 0, 0)) { | 2224 | av7110->fe->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params; |
2225 | av7110->fe->tuner_priv = &av7110->i2c_adap; | ||
2226 | |||
2227 | if (lnbp21_attach(av7110->fe, &av7110->i2c_adap, 0, 0)) { | ||
2193 | printk("dvb-ttpci: LNBP21 not found!\n"); | 2228 | printk("dvb-ttpci: LNBP21 not found!\n"); |
2194 | if (av7110->fe->ops->release) | 2229 | if (av7110->fe->ops.release) |
2195 | av7110->fe->ops->release(av7110->fe); | 2230 | av7110->fe->ops.release(av7110->fe); |
2196 | av7110->fe = NULL; | 2231 | av7110->fe = NULL; |
2197 | } else { | 2232 | } else { |
2198 | av7110->fe->ops->dishnetwork_send_legacy_command = NULL; | 2233 | av7110->fe->ops.dishnetwork_send_legacy_command = NULL; |
2199 | av7110->recover = dvb_s_recover; | 2234 | av7110->recover = dvb_s_recover; |
2200 | } | 2235 | } |
2201 | } | 2236 | } |
@@ -2212,21 +2247,21 @@ static int frontend_init(struct av7110 *av7110) | |||
2212 | av7110->dev->pci->subsystem_vendor, | 2247 | av7110->dev->pci->subsystem_vendor, |
2213 | av7110->dev->pci->subsystem_device); | 2248 | av7110->dev->pci->subsystem_device); |
2214 | } else { | 2249 | } else { |
2215 | FE_FUNC_OVERRIDE(av7110->fe->ops->init, av7110->fe_init, av7110_fe_init); | 2250 | FE_FUNC_OVERRIDE(av7110->fe->ops.init, av7110->fe_init, av7110_fe_init); |
2216 | FE_FUNC_OVERRIDE(av7110->fe->ops->read_status, av7110->fe_read_status, av7110_fe_read_status); | 2251 | FE_FUNC_OVERRIDE(av7110->fe->ops.read_status, av7110->fe_read_status, av7110_fe_read_status); |
2217 | FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_reset_overload, av7110->fe_diseqc_reset_overload, av7110_fe_diseqc_reset_overload); | 2252 | FE_FUNC_OVERRIDE(av7110->fe->ops.diseqc_reset_overload, av7110->fe_diseqc_reset_overload, av7110_fe_diseqc_reset_overload); |
2218 | FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_send_master_cmd, av7110->fe_diseqc_send_master_cmd, av7110_fe_diseqc_send_master_cmd); | 2253 | FE_FUNC_OVERRIDE(av7110->fe->ops.diseqc_send_master_cmd, av7110->fe_diseqc_send_master_cmd, av7110_fe_diseqc_send_master_cmd); |
2219 | FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_send_burst, av7110->fe_diseqc_send_burst, av7110_fe_diseqc_send_burst); | 2254 | FE_FUNC_OVERRIDE(av7110->fe->ops.diseqc_send_burst, av7110->fe_diseqc_send_burst, av7110_fe_diseqc_send_burst); |
2220 | FE_FUNC_OVERRIDE(av7110->fe->ops->set_tone, av7110->fe_set_tone, av7110_fe_set_tone); | 2255 | FE_FUNC_OVERRIDE(av7110->fe->ops.set_tone, av7110->fe_set_tone, av7110_fe_set_tone); |
2221 | FE_FUNC_OVERRIDE(av7110->fe->ops->set_voltage, av7110->fe_set_voltage, av7110_fe_set_voltage;) | 2256 | FE_FUNC_OVERRIDE(av7110->fe->ops.set_voltage, av7110->fe_set_voltage, av7110_fe_set_voltage;) |
2222 | FE_FUNC_OVERRIDE(av7110->fe->ops->dishnetwork_send_legacy_command, av7110->fe_dishnetwork_send_legacy_command, av7110_fe_dishnetwork_send_legacy_command); | 2257 | FE_FUNC_OVERRIDE(av7110->fe->ops.dishnetwork_send_legacy_command, av7110->fe_dishnetwork_send_legacy_command, av7110_fe_dishnetwork_send_legacy_command); |
2223 | FE_FUNC_OVERRIDE(av7110->fe->ops->set_frontend, av7110->fe_set_frontend, av7110_fe_set_frontend); | 2258 | FE_FUNC_OVERRIDE(av7110->fe->ops.set_frontend, av7110->fe_set_frontend, av7110_fe_set_frontend); |
2224 | 2259 | ||
2225 | ret = dvb_register_frontend(&av7110->dvb_adapter, av7110->fe); | 2260 | ret = dvb_register_frontend(&av7110->dvb_adapter, av7110->fe); |
2226 | if (ret < 0) { | 2261 | if (ret < 0) { |
2227 | printk("av7110: Frontend registration failed!\n"); | 2262 | printk("av7110: Frontend registration failed!\n"); |
2228 | if (av7110->fe->ops->release) | 2263 | if (av7110->fe->ops.release) |
2229 | av7110->fe->ops->release(av7110->fe); | 2264 | av7110->fe->ops.release(av7110->fe); |
2230 | av7110->fe = NULL; | 2265 | av7110->fe = NULL; |
2231 | } | 2266 | } |
2232 | } | 2267 | } |
@@ -2413,7 +2448,7 @@ static int __devinit av7110_attach(struct saa7146_dev* dev, | |||
2413 | goto err_kfree_0; | 2448 | goto err_kfree_0; |
2414 | 2449 | ||
2415 | ret = dvb_register_adapter(&av7110->dvb_adapter, av7110->card_name, | 2450 | ret = dvb_register_adapter(&av7110->dvb_adapter, av7110->card_name, |
2416 | THIS_MODULE); | 2451 | THIS_MODULE, &dev->pci->dev); |
2417 | if (ret < 0) | 2452 | if (ret < 0) |
2418 | goto err_put_firmware_1; | 2453 | goto err_put_firmware_1; |
2419 | 2454 | ||
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c index 8a7cd7d505cf..6163cb03b8f4 100644 --- a/drivers/media/dvb/ttpci/budget-av.c +++ b/drivers/media/dvb/ttpci/budget-av.c | |||
@@ -50,6 +50,12 @@ | |||
50 | 50 | ||
51 | #define DEBICICAM 0x02420000 | 51 | #define DEBICICAM 0x02420000 |
52 | 52 | ||
53 | #define SLOTSTATUS_NONE 1 | ||
54 | #define SLOTSTATUS_PRESENT 2 | ||
55 | #define SLOTSTATUS_RESET 4 | ||
56 | #define SLOTSTATUS_READY 8 | ||
57 | #define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY) | ||
58 | |||
53 | struct budget_av { | 59 | struct budget_av { |
54 | struct budget budget; | 60 | struct budget budget; |
55 | struct video_device *vd; | 61 | struct video_device *vd; |
@@ -58,8 +64,15 @@ struct budget_av { | |||
58 | struct tasklet_struct ciintf_irq_tasklet; | 64 | struct tasklet_struct ciintf_irq_tasklet; |
59 | int slot_status; | 65 | int slot_status; |
60 | struct dvb_ca_en50221 ca; | 66 | struct dvb_ca_en50221 ca; |
67 | u8 reinitialise_demod:1; | ||
68 | u8 tda10021_poclkp:1; | ||
69 | u8 tda10021_ts_enabled; | ||
70 | int (*tda10021_set_frontend)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p); | ||
61 | }; | 71 | }; |
62 | 72 | ||
73 | static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot); | ||
74 | |||
75 | |||
63 | /* GPIO Connections: | 76 | /* GPIO Connections: |
64 | * 0 - Vcc/Reset (Reset is controlled by capacitor). Resets the frontend *AS WELL*! | 77 | * 0 - Vcc/Reset (Reset is controlled by capacitor). Resets the frontend *AS WELL*! |
65 | * 1 - CI memory select 0=>IO memory, 1=>Attribute Memory | 78 | * 1 - CI memory select 0=>IO memory, 1=>Attribute Memory |
@@ -129,9 +142,10 @@ static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int ad | |||
129 | udelay(1); | 142 | udelay(1); |
130 | 143 | ||
131 | result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 0xfff, 1, 0, 1); | 144 | result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 0xfff, 1, 0, 1); |
132 | 145 | if (result == -ETIMEDOUT) { | |
133 | if (result == -ETIMEDOUT) | 146 | ciintf_slot_shutdown(ca, slot); |
134 | budget_av->slot_status = 0; | 147 | printk(KERN_INFO "budget-av: cam ejected 1\n"); |
148 | } | ||
135 | return result; | 149 | return result; |
136 | } | 150 | } |
137 | 151 | ||
@@ -147,9 +161,10 @@ static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int a | |||
147 | udelay(1); | 161 | udelay(1); |
148 | 162 | ||
149 | result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 0xfff, 1, value, 0, 1); | 163 | result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 0xfff, 1, value, 0, 1); |
150 | 164 | if (result == -ETIMEDOUT) { | |
151 | if (result == -ETIMEDOUT) | 165 | ciintf_slot_shutdown(ca, slot); |
152 | budget_av->slot_status = 0; | 166 | printk(KERN_INFO "budget-av: cam ejected 2\n"); |
167 | } | ||
153 | return result; | 168 | return result; |
154 | } | 169 | } |
155 | 170 | ||
@@ -165,9 +180,11 @@ static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 addre | |||
165 | udelay(1); | 180 | udelay(1); |
166 | 181 | ||
167 | result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 3, 1, 0, 0); | 182 | result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 3, 1, 0, 0); |
168 | 183 | if ((result == -ETIMEDOUT) || ((result == 0xff) && ((address & 3) < 2))) { | |
169 | if (result == -ETIMEDOUT) | 184 | ciintf_slot_shutdown(ca, slot); |
170 | budget_av->slot_status = 0; | 185 | printk(KERN_INFO "budget-av: cam ejected 3\n"); |
186 | return -ETIMEDOUT; | ||
187 | } | ||
171 | return result; | 188 | return result; |
172 | } | 189 | } |
173 | 190 | ||
@@ -183,9 +200,10 @@ static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 addr | |||
183 | udelay(1); | 200 | udelay(1); |
184 | 201 | ||
185 | result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 3, 1, value, 0, 0); | 202 | result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 3, 1, value, 0, 0); |
186 | 203 | if (result == -ETIMEDOUT) { | |
187 | if (result == -ETIMEDOUT) | 204 | ciintf_slot_shutdown(ca, slot); |
188 | budget_av->slot_status = 0; | 205 | printk(KERN_INFO "budget-av: cam ejected 5\n"); |
206 | } | ||
189 | return result; | 207 | return result; |
190 | } | 208 | } |
191 | 209 | ||
@@ -193,12 +211,12 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot) | |||
193 | { | 211 | { |
194 | struct budget_av *budget_av = (struct budget_av *) ca->data; | 212 | struct budget_av *budget_av = (struct budget_av *) ca->data; |
195 | struct saa7146_dev *saa = budget_av->budget.dev; | 213 | struct saa7146_dev *saa = budget_av->budget.dev; |
196 | int timeout = 50; // 5 seconds (4.4.6 Ready) | ||
197 | 214 | ||
198 | if (slot != 0) | 215 | if (slot != 0) |
199 | return -EINVAL; | 216 | return -EINVAL; |
200 | 217 | ||
201 | dprintk(1, "ciintf_slot_reset\n"); | 218 | dprintk(1, "ciintf_slot_reset\n"); |
219 | budget_av->slot_status = SLOTSTATUS_RESET; | ||
202 | 220 | ||
203 | saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */ | 221 | saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */ |
204 | 222 | ||
@@ -208,20 +226,17 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot) | |||
208 | msleep(20); /* 20 ms Vcc settling time */ | 226 | msleep(20); /* 20 ms Vcc settling time */ |
209 | 227 | ||
210 | saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO); /* enable card */ | 228 | saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO); /* enable card */ |
229 | ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB); | ||
230 | msleep(20); | ||
211 | 231 | ||
212 | /* This should have been based on pin 16 READY of the pcmcia port, | 232 | /* reinitialise the frontend if necessary */ |
213 | * but AFAICS it is not routed to the saa7146 */ | 233 | if (budget_av->reinitialise_demod) |
214 | while (--timeout > 0 && ciintf_read_attribute_mem(ca, slot, 0) != 0x1d) | 234 | dvb_frontend_reinitialise(budget_av->budget.dvb_frontend); |
215 | msleep(100); | ||
216 | |||
217 | /* reinitialise the frontend */ | ||
218 | dvb_frontend_reinitialise(budget_av->budget.dvb_frontend); | ||
219 | 235 | ||
220 | if (timeout <= 0) | 236 | /* set tda10021 back to original clock configuration on reset */ |
221 | { | 237 | if (budget_av->tda10021_poclkp) { |
222 | printk(KERN_ERR "budget-av: cam reset failed (timeout).\n"); | 238 | tda10021_write_byte(budget_av->budget.dvb_frontend, 0x12, 0xa0); |
223 | saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */ | 239 | budget_av->tda10021_ts_enabled = 0; |
224 | return -ETIMEDOUT; | ||
225 | } | 240 | } |
226 | 241 | ||
227 | return 0; | 242 | return 0; |
@@ -238,7 +253,13 @@ static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot) | |||
238 | dprintk(1, "ciintf_slot_shutdown\n"); | 253 | dprintk(1, "ciintf_slot_shutdown\n"); |
239 | 254 | ||
240 | ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB); | 255 | ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB); |
241 | budget_av->slot_status = 0; | 256 | budget_av->slot_status = SLOTSTATUS_NONE; |
257 | |||
258 | /* set tda10021 back to original clock configuration when cam removed */ | ||
259 | if (budget_av->tda10021_poclkp) { | ||
260 | tda10021_write_byte(budget_av->budget.dvb_frontend, 0x12, 0xa0); | ||
261 | budget_av->tda10021_ts_enabled = 0; | ||
262 | } | ||
242 | return 0; | 263 | return 0; |
243 | } | 264 | } |
244 | 265 | ||
@@ -253,6 +274,13 @@ static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot) | |||
253 | dprintk(1, "ciintf_slot_ts_enable: %d\n", budget_av->slot_status); | 274 | dprintk(1, "ciintf_slot_ts_enable: %d\n", budget_av->slot_status); |
254 | 275 | ||
255 | ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA); | 276 | ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA); |
277 | |||
278 | /* tda10021 seems to need a different TS clock config when data is routed to the CAM */ | ||
279 | if (budget_av->tda10021_poclkp) { | ||
280 | tda10021_write_byte(budget_av->budget.dvb_frontend, 0x12, 0xa1); | ||
281 | budget_av->tda10021_ts_enabled = 1; | ||
282 | } | ||
283 | |||
256 | return 0; | 284 | return 0; |
257 | } | 285 | } |
258 | 286 | ||
@@ -260,50 +288,61 @@ static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open | |||
260 | { | 288 | { |
261 | struct budget_av *budget_av = (struct budget_av *) ca->data; | 289 | struct budget_av *budget_av = (struct budget_av *) ca->data; |
262 | struct saa7146_dev *saa = budget_av->budget.dev; | 290 | struct saa7146_dev *saa = budget_av->budget.dev; |
263 | int cam_present = 0; | 291 | int result; |
264 | 292 | ||
265 | if (slot != 0) | 293 | if (slot != 0) |
266 | return -EINVAL; | 294 | return -EINVAL; |
267 | 295 | ||
268 | if (!budget_av->slot_status) | 296 | /* test the card detect line - needs to be done carefully |
269 | { | 297 | * since it never goes high for some CAMs on this interface (e.g. topuptv) */ |
270 | // first of all test the card detect line | 298 | if (budget_av->slot_status == SLOTSTATUS_NONE) { |
271 | saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); | 299 | saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); |
272 | udelay(1); | 300 | udelay(1); |
273 | if (saa7146_read(saa, PSR) & MASK_06) | 301 | if (saa7146_read(saa, PSR) & MASK_06) { |
274 | { | 302 | if (budget_av->slot_status == SLOTSTATUS_NONE) { |
275 | cam_present = 1; | 303 | budget_av->slot_status = SLOTSTATUS_PRESENT; |
304 | printk(KERN_INFO "budget-av: cam inserted A\n"); | ||
305 | } | ||
276 | } | 306 | } |
277 | saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO); | 307 | saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO); |
308 | } | ||
278 | 309 | ||
279 | // that is unreliable however, so try and read from IO memory | 310 | /* We also try and read from IO memory to work round the above detection bug. If |
280 | if (!cam_present) | 311 | * there is no CAM, we will get a timeout. Only done if there is no cam |
281 | { | 312 | * present, since this test actually breaks some cams :( |
282 | saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); | 313 | * |
283 | if (ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1) != -ETIMEDOUT) | 314 | * if the CI interface is not open, we also do the above test since we |
284 | { | 315 | * don't care if the cam has problems - we'll be resetting it on open() anyway */ |
285 | cam_present = 1; | 316 | if ((budget_av->slot_status == SLOTSTATUS_NONE) || (!open)) { |
317 | saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); | ||
318 | result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1); | ||
319 | if ((result >= 0) && (budget_av->slot_status == SLOTSTATUS_NONE)) { | ||
320 | budget_av->slot_status = SLOTSTATUS_PRESENT; | ||
321 | printk(KERN_INFO "budget-av: cam inserted B\n"); | ||
322 | } else if (result < 0) { | ||
323 | if (budget_av->slot_status != SLOTSTATUS_NONE) { | ||
324 | ciintf_slot_shutdown(ca, slot); | ||
325 | printk(KERN_INFO "budget-av: cam ejected 5\n"); | ||
326 | return 0; | ||
286 | } | 327 | } |
287 | } | 328 | } |
329 | } | ||
288 | 330 | ||
289 | // did we find something? | 331 | /* read from attribute memory in reset/ready state to know when the CAM is ready */ |
290 | if (cam_present) { | 332 | if (budget_av->slot_status == SLOTSTATUS_RESET) { |
291 | printk(KERN_INFO "budget-av: cam inserted\n"); | 333 | result = ciintf_read_attribute_mem(ca, slot, 0); |
292 | budget_av->slot_status = 1; | 334 | if (result == 0x1d) { |
293 | } | 335 | budget_av->slot_status = SLOTSTATUS_READY; |
294 | } else if (!open) { | ||
295 | saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); | ||
296 | if (ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1) == -ETIMEDOUT) | ||
297 | { | ||
298 | printk(KERN_INFO "budget-av: cam ejected\n"); | ||
299 | saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */ | ||
300 | budget_av->slot_status = 0; | ||
301 | } | 336 | } |
302 | } | 337 | } |
303 | 338 | ||
304 | if (budget_av->slot_status == 1) | 339 | /* work out correct return code */ |
305 | return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY; | 340 | if (budget_av->slot_status != SLOTSTATUS_NONE) { |
306 | 341 | if (budget_av->slot_status & SLOTSTATUS_READY) { | |
342 | return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY; | ||
343 | } | ||
344 | return DVB_CA_EN50221_POLL_CAM_PRESENT; | ||
345 | } | ||
307 | return 0; | 346 | return 0; |
308 | } | 347 | } |
309 | 348 | ||
@@ -333,6 +372,8 @@ static int ciintf_init(struct budget_av *budget_av) | |||
333 | budget_av->ca.slot_ts_enable = ciintf_slot_ts_enable; | 372 | budget_av->ca.slot_ts_enable = ciintf_slot_ts_enable; |
334 | budget_av->ca.poll_slot_status = ciintf_poll_slot_status; | 373 | budget_av->ca.poll_slot_status = ciintf_poll_slot_status; |
335 | budget_av->ca.data = budget_av; | 374 | budget_av->ca.data = budget_av; |
375 | budget_av->budget.ci_present = 1; | ||
376 | budget_av->slot_status = SLOTSTATUS_NONE; | ||
336 | 377 | ||
337 | if ((result = dvb_ca_en50221_init(&budget_av->budget.dvb_adapter, | 378 | if ((result = dvb_ca_en50221_init(&budget_av->budget.dvb_adapter, |
338 | &budget_av->ca, 0, 1)) != 0) { | 379 | &budget_av->ca, 0, 1)) != 0) { |
@@ -341,7 +382,6 @@ static int ciintf_init(struct budget_av *budget_av) | |||
341 | } | 382 | } |
342 | 383 | ||
343 | printk(KERN_INFO "budget-av: ci interface initialised.\n"); | 384 | printk(KERN_INFO "budget-av: ci interface initialised.\n"); |
344 | budget_av->budget.ci_present = 1; | ||
345 | return 0; | 385 | return 0; |
346 | 386 | ||
347 | error: | 387 | error: |
@@ -472,12 +512,12 @@ static int philips_su1278_ty_ci_set_symbol_rate(struct dvb_frontend *fe, u32 sra | |||
472 | return 0; | 512 | return 0; |
473 | } | 513 | } |
474 | 514 | ||
475 | static int philips_su1278_ty_ci_pll_set(struct dvb_frontend *fe, | 515 | static int philips_su1278_ty_ci_tuner_set_params(struct dvb_frontend *fe, |
476 | struct i2c_adapter *i2c, | 516 | struct dvb_frontend_parameters *params) |
477 | struct dvb_frontend_parameters *params) | ||
478 | { | 517 | { |
479 | u32 div; | 518 | u32 div; |
480 | u8 buf[4]; | 519 | u8 buf[4]; |
520 | struct budget *budget = (struct budget *) fe->dvb->priv; | ||
481 | struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) }; | 521 | struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) }; |
482 | 522 | ||
483 | if ((params->frequency < 950000) || (params->frequency > 2150000)) | 523 | if ((params->frequency < 950000) || (params->frequency > 2150000)) |
@@ -501,7 +541,9 @@ static int philips_su1278_ty_ci_pll_set(struct dvb_frontend *fe, | |||
501 | else if (params->frequency < 2150000) | 541 | else if (params->frequency < 2150000) |
502 | buf[3] |= 0xC0; | 542 | buf[3] |= 0xC0; |
503 | 543 | ||
504 | if (i2c_transfer(i2c, &msg, 1) != 1) | 544 | if (fe->ops.i2c_gate_ctrl) |
545 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
546 | if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) | ||
505 | return -EIO; | 547 | return -EIO; |
506 | return 0; | 548 | return 0; |
507 | } | 549 | } |
@@ -509,9 +551,8 @@ static int philips_su1278_ty_ci_pll_set(struct dvb_frontend *fe, | |||
509 | #define MIN2(a,b) ((a) < (b) ? (a) : (b)) | 551 | #define MIN2(a,b) ((a) < (b) ? (a) : (b)) |
510 | #define MIN3(a,b,c) MIN2(MIN2(a,b),c) | 552 | #define MIN3(a,b,c) MIN2(MIN2(a,b),c) |
511 | 553 | ||
512 | static int philips_su1278sh2_tua6100_pll_set(struct dvb_frontend *fe, | 554 | static int philips_su1278sh2_tua6100_tuner_set_params(struct dvb_frontend *fe, |
513 | struct i2c_adapter *i2c, | 555 | struct dvb_frontend_parameters *params) |
514 | struct dvb_frontend_parameters *params) | ||
515 | { | 556 | { |
516 | u8 reg0 [2] = { 0x00, 0x00 }; | 557 | u8 reg0 [2] = { 0x00, 0x00 }; |
517 | u8 reg1 [4] = { 0x01, 0x00, 0x00, 0x00 }; | 558 | u8 reg1 [4] = { 0x01, 0x00, 0x00, 0x00 }; |
@@ -521,6 +562,7 @@ static int philips_su1278sh2_tua6100_pll_set(struct dvb_frontend *fe, | |||
521 | int R, A, N, P, M; | 562 | int R, A, N, P, M; |
522 | struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = NULL,.len = 0 }; | 563 | struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = NULL,.len = 0 }; |
523 | int freq = params->frequency; | 564 | int freq = params->frequency; |
565 | struct budget *budget = (struct budget *) fe->dvb->priv; | ||
524 | 566 | ||
525 | first_ZF = (freq) / 1000; | 567 | first_ZF = (freq) / 1000; |
526 | 568 | ||
@@ -620,21 +662,25 @@ static int philips_su1278sh2_tua6100_pll_set(struct dvb_frontend *fe, | |||
620 | reg0[1] |= 0x03; | 662 | reg0[1] |= 0x03; |
621 | 663 | ||
622 | /* already enabled - do not reenable i2c repeater or TX fails */ | 664 | /* already enabled - do not reenable i2c repeater or TX fails */ |
665 | if (fe->ops.i2c_gate_ctrl) | ||
666 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
623 | msg.buf = reg0; | 667 | msg.buf = reg0; |
624 | msg.len = sizeof(reg0); | 668 | msg.len = sizeof(reg0); |
625 | if (i2c_transfer(i2c, &msg, 1) != 1) | 669 | if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) |
626 | return -EIO; | 670 | return -EIO; |
627 | 671 | ||
628 | stv0299_enable_plli2c(fe); | 672 | if (fe->ops.i2c_gate_ctrl) |
673 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
629 | msg.buf = reg1; | 674 | msg.buf = reg1; |
630 | msg.len = sizeof(reg1); | 675 | msg.len = sizeof(reg1); |
631 | if (i2c_transfer(i2c, &msg, 1) != 1) | 676 | if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) |
632 | return -EIO; | 677 | return -EIO; |
633 | 678 | ||
634 | stv0299_enable_plli2c(fe); | 679 | if (fe->ops.i2c_gate_ctrl) |
680 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
635 | msg.buf = reg2; | 681 | msg.buf = reg2; |
636 | msg.len = sizeof(reg2); | 682 | msg.len = sizeof(reg2); |
637 | if (i2c_transfer(i2c, &msg, 1) != 1) | 683 | if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) |
638 | return -EIO; | 684 | return -EIO; |
639 | 685 | ||
640 | return 0; | 686 | return 0; |
@@ -692,7 +738,6 @@ static struct stv0299_config typhoon_config = { | |||
692 | .volt13_op0_op1 = STV0299_VOLT13_OP0, | 738 | .volt13_op0_op1 = STV0299_VOLT13_OP0, |
693 | .min_delay_ms = 100, | 739 | .min_delay_ms = 100, |
694 | .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, | 740 | .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, |
695 | .pll_set = philips_su1278_ty_ci_pll_set, | ||
696 | }; | 741 | }; |
697 | 742 | ||
698 | 743 | ||
@@ -706,7 +751,6 @@ static struct stv0299_config cinergy_1200s_config = { | |||
706 | .volt13_op0_op1 = STV0299_VOLT13_OP0, | 751 | .volt13_op0_op1 = STV0299_VOLT13_OP0, |
707 | .min_delay_ms = 100, | 752 | .min_delay_ms = 100, |
708 | .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, | 753 | .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, |
709 | .pll_set = philips_su1278_ty_ci_pll_set, | ||
710 | }; | 754 | }; |
711 | 755 | ||
712 | static struct stv0299_config cinergy_1200s_1894_0010_config = { | 756 | static struct stv0299_config cinergy_1200s_1894_0010_config = { |
@@ -719,10 +763,9 @@ static struct stv0299_config cinergy_1200s_1894_0010_config = { | |||
719 | .volt13_op0_op1 = STV0299_VOLT13_OP0, | 763 | .volt13_op0_op1 = STV0299_VOLT13_OP0, |
720 | .min_delay_ms = 100, | 764 | .min_delay_ms = 100, |
721 | .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, | 765 | .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, |
722 | .pll_set = philips_su1278sh2_tua6100_pll_set, | ||
723 | }; | 766 | }; |
724 | 767 | ||
725 | static int philips_cu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | 768 | static int philips_cu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) |
726 | { | 769 | { |
727 | struct budget *budget = (struct budget *) fe->dvb->priv; | 770 | struct budget *budget = (struct budget *) fe->dvb->priv; |
728 | u8 buf[4]; | 771 | u8 buf[4]; |
@@ -738,6 +781,8 @@ static int philips_cu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_p | |||
738 | buf[3] = (params->frequency < 150000000 ? 0x01 : | 781 | buf[3] = (params->frequency < 150000000 ? 0x01 : |
739 | params->frequency < 445000000 ? 0x02 : 0x04); | 782 | params->frequency < 445000000 ? 0x02 : 0x04); |
740 | 783 | ||
784 | if (fe->ops.i2c_gate_ctrl) | ||
785 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
741 | if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) | 786 | if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) |
742 | return -EIO; | 787 | return -EIO; |
743 | return 0; | 788 | return 0; |
@@ -745,19 +790,20 @@ static int philips_cu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_p | |||
745 | 790 | ||
746 | static struct tda10021_config philips_cu1216_config = { | 791 | static struct tda10021_config philips_cu1216_config = { |
747 | .demod_address = 0x0c, | 792 | .demod_address = 0x0c, |
748 | .pll_set = philips_cu1216_pll_set, | ||
749 | }; | 793 | }; |
750 | 794 | ||
751 | 795 | ||
752 | 796 | ||
753 | 797 | ||
754 | static int philips_tu1216_pll_init(struct dvb_frontend *fe) | 798 | static int philips_tu1216_tuner_init(struct dvb_frontend *fe) |
755 | { | 799 | { |
756 | struct budget *budget = (struct budget *) fe->dvb->priv; | 800 | struct budget *budget = (struct budget *) fe->dvb->priv; |
757 | static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab }; | 801 | static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab }; |
758 | struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) }; | 802 | struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) }; |
759 | 803 | ||
760 | // setup PLL configuration | 804 | // setup PLL configuration |
805 | if (fe->ops.i2c_gate_ctrl) | ||
806 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
761 | if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1) | 807 | if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1) |
762 | return -EIO; | 808 | return -EIO; |
763 | msleep(1); | 809 | msleep(1); |
@@ -765,7 +811,7 @@ static int philips_tu1216_pll_init(struct dvb_frontend *fe) | |||
765 | return 0; | 811 | return 0; |
766 | } | 812 | } |
767 | 813 | ||
768 | static int philips_tu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | 814 | static int philips_tu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) |
769 | { | 815 | { |
770 | struct budget *budget = (struct budget *) fe->dvb->priv; | 816 | struct budget *budget = (struct budget *) fe->dvb->priv; |
771 | u8 tuner_buf[4]; | 817 | u8 tuner_buf[4]; |
@@ -839,6 +885,8 @@ static int philips_tu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_p | |||
839 | tuner_buf[2] = 0xca; | 885 | tuner_buf[2] = 0xca; |
840 | tuner_buf[3] = (cp << 5) | (filter << 3) | band; | 886 | tuner_buf[3] = (cp << 5) | (filter << 3) | band; |
841 | 887 | ||
888 | if (fe->ops.i2c_gate_ctrl) | ||
889 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
842 | if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1) | 890 | if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1) |
843 | return -EIO; | 891 | return -EIO; |
844 | 892 | ||
@@ -862,9 +910,6 @@ static struct tda1004x_config philips_tu1216_config = { | |||
862 | .xtal_freq = TDA10046_XTAL_4M, | 910 | .xtal_freq = TDA10046_XTAL_4M, |
863 | .agc_config = TDA10046_AGC_DEFAULT, | 911 | .agc_config = TDA10046_AGC_DEFAULT, |
864 | .if_freq = TDA10046_FREQ_3617, | 912 | .if_freq = TDA10046_FREQ_3617, |
865 | .pll_init = philips_tu1216_pll_init, | ||
866 | .pll_set = philips_tu1216_pll_set, | ||
867 | .pll_sleep = NULL, | ||
868 | .request_firmware = philips_tu1216_request_firmware, | 913 | .request_firmware = philips_tu1216_request_firmware, |
869 | }; | 914 | }; |
870 | 915 | ||
@@ -911,13 +956,13 @@ static u8 philips_sd1878_inittab[] = { | |||
911 | 0xff, 0xff | 956 | 0xff, 0xff |
912 | }; | 957 | }; |
913 | 958 | ||
914 | static int philips_sd1878_tda8261_pll_set(struct dvb_frontend *fe, | 959 | static int philips_sd1878_tda8261_tuner_set_params(struct dvb_frontend *fe, |
915 | struct i2c_adapter *i2c, | 960 | struct dvb_frontend_parameters *params) |
916 | struct dvb_frontend_parameters *params) | ||
917 | { | 961 | { |
918 | u8 buf[4]; | 962 | u8 buf[4]; |
919 | int rc; | 963 | int rc; |
920 | struct i2c_msg tuner_msg = {.addr=0x60,.flags=0,.buf=buf,.len=sizeof(buf)}; | 964 | struct i2c_msg tuner_msg = {.addr=0x60,.flags=0,.buf=buf,.len=sizeof(buf)}; |
965 | struct budget *budget = (struct budget *) fe->dvb->priv; | ||
921 | 966 | ||
922 | if((params->frequency < 950000) || (params->frequency > 2150000)) | 967 | if((params->frequency < 950000) || (params->frequency > 2150000)) |
923 | return -EINVAL; | 968 | return -EINVAL; |
@@ -926,7 +971,9 @@ static int philips_sd1878_tda8261_pll_set(struct dvb_frontend *fe, | |||
926 | params->frequency, 0); | 971 | params->frequency, 0); |
927 | if(rc < 0) return rc; | 972 | if(rc < 0) return rc; |
928 | 973 | ||
929 | if(i2c_transfer(i2c, &tuner_msg, 1) != 1) | 974 | if (fe->ops.i2c_gate_ctrl) |
975 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
976 | if(i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1) | ||
930 | return -EIO; | 977 | return -EIO; |
931 | 978 | ||
932 | return 0; | 979 | return 0; |
@@ -969,7 +1016,7 @@ static int philips_sd1878_ci_set_symbol_rate(struct dvb_frontend *fe, | |||
969 | 1016 | ||
970 | static struct stv0299_config philips_sd1878_config = { | 1017 | static struct stv0299_config philips_sd1878_config = { |
971 | .demod_address = 0x68, | 1018 | .demod_address = 0x68, |
972 | .inittab = philips_sd1878_inittab, | 1019 | .inittab = philips_sd1878_inittab, |
973 | .mclk = 88000000UL, | 1020 | .mclk = 88000000UL, |
974 | .invert = 0, | 1021 | .invert = 0, |
975 | .skip_reinit = 0, | 1022 | .skip_reinit = 0, |
@@ -977,7 +1024,6 @@ static struct stv0299_config philips_sd1878_config = { | |||
977 | .volt13_op0_op1 = STV0299_VOLT13_OP0, | 1024 | .volt13_op0_op1 = STV0299_VOLT13_OP0, |
978 | .min_delay_ms = 100, | 1025 | .min_delay_ms = 100, |
979 | .set_symbol_rate = philips_sd1878_ci_set_symbol_rate, | 1026 | .set_symbol_rate = philips_sd1878_ci_set_symbol_rate, |
980 | .pll_set = philips_sd1878_tda8261_pll_set, | ||
981 | }; | 1027 | }; |
982 | 1028 | ||
983 | static u8 read_pwm(struct budget_av *budget_av) | 1029 | static u8 read_pwm(struct budget_av *budget_av) |
@@ -1003,6 +1049,7 @@ static u8 read_pwm(struct budget_av *budget_av) | |||
1003 | 1049 | ||
1004 | #define SUBID_DVBS_TV_STAR 0x0014 | 1050 | #define SUBID_DVBS_TV_STAR 0x0014 |
1005 | #define SUBID_DVBS_TV_STAR_CI 0x0016 | 1051 | #define SUBID_DVBS_TV_STAR_CI 0x0016 |
1052 | #define SUBID_DVBS_EASYWATCH_1 0x001a | ||
1006 | #define SUBID_DVBS_EASYWATCH 0x001e | 1053 | #define SUBID_DVBS_EASYWATCH 0x001e |
1007 | #define SUBID_DVBC_KNC1 0x0020 | 1054 | #define SUBID_DVBC_KNC1 0x0020 |
1008 | #define SUBID_DVBC_KNC1_PLUS 0x0021 | 1055 | #define SUBID_DVBC_KNC1_PLUS 0x0021 |
@@ -1012,17 +1059,36 @@ static u8 read_pwm(struct budget_av *budget_av) | |||
1012 | #define SUBID_DVBT_KNC1 0x0030 | 1059 | #define SUBID_DVBT_KNC1 0x0030 |
1013 | #define SUBID_DVBT_CINERGY1200 0x1157 | 1060 | #define SUBID_DVBT_CINERGY1200 0x1157 |
1014 | 1061 | ||
1062 | |||
1063 | static int tda10021_set_frontend(struct dvb_frontend *fe, | ||
1064 | struct dvb_frontend_parameters *p) | ||
1065 | { | ||
1066 | struct budget_av* budget_av = fe->dvb->priv; | ||
1067 | int result; | ||
1068 | |||
1069 | result = budget_av->tda10021_set_frontend(fe, p); | ||
1070 | if (budget_av->tda10021_ts_enabled) { | ||
1071 | tda10021_write_byte(budget_av->budget.dvb_frontend, 0x12, 0xa1); | ||
1072 | } else { | ||
1073 | tda10021_write_byte(budget_av->budget.dvb_frontend, 0x12, 0xa0); | ||
1074 | } | ||
1075 | |||
1076 | return result; | ||
1077 | } | ||
1078 | |||
1015 | static void frontend_init(struct budget_av *budget_av) | 1079 | static void frontend_init(struct budget_av *budget_av) |
1016 | { | 1080 | { |
1017 | struct saa7146_dev * saa = budget_av->budget.dev; | 1081 | struct saa7146_dev * saa = budget_av->budget.dev; |
1018 | struct dvb_frontend * fe = NULL; | 1082 | struct dvb_frontend * fe = NULL; |
1019 | 1083 | ||
1084 | /* Enable / PowerON Frontend */ | ||
1085 | saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); | ||
1086 | |||
1087 | /* additional setup necessary for the PLUS cards */ | ||
1020 | switch (saa->pci->subsystem_device) { | 1088 | switch (saa->pci->subsystem_device) { |
1021 | case SUBID_DVBS_KNC1_PLUS: | 1089 | case SUBID_DVBS_KNC1_PLUS: |
1022 | case SUBID_DVBC_KNC1_PLUS: | 1090 | case SUBID_DVBC_KNC1_PLUS: |
1023 | case SUBID_DVBT_KNC1_PLUS: | 1091 | case SUBID_DVBT_KNC1_PLUS: |
1024 | // Enable / PowerON Frontend | ||
1025 | saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); | ||
1026 | saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI); | 1092 | saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI); |
1027 | break; | 1093 | break; |
1028 | } | 1094 | } |
@@ -1030,12 +1096,19 @@ static void frontend_init(struct budget_av *budget_av) | |||
1030 | switch (saa->pci->subsystem_device) { | 1096 | switch (saa->pci->subsystem_device) { |
1031 | 1097 | ||
1032 | case SUBID_DVBS_KNC1: | 1098 | case SUBID_DVBS_KNC1: |
1099 | case SUBID_DVBS_EASYWATCH_1: | ||
1033 | if (saa->pci->subsystem_vendor == 0x1894) { | 1100 | if (saa->pci->subsystem_vendor == 0x1894) { |
1034 | fe = stv0299_attach(&cinergy_1200s_1894_0010_config, | 1101 | fe = stv0299_attach(&cinergy_1200s_1894_0010_config, |
1035 | &budget_av->budget.i2c_adap); | 1102 | &budget_av->budget.i2c_adap); |
1103 | if (fe) { | ||
1104 | fe->ops.tuner_ops.set_params = philips_su1278sh2_tua6100_tuner_set_params; | ||
1105 | } | ||
1036 | } else { | 1106 | } else { |
1037 | fe = stv0299_attach(&typhoon_config, | 1107 | fe = stv0299_attach(&typhoon_config, |
1038 | &budget_av->budget.i2c_adap); | 1108 | &budget_av->budget.i2c_adap); |
1109 | if (fe) { | ||
1110 | fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params; | ||
1111 | } | ||
1039 | } | 1112 | } |
1040 | break; | 1113 | break; |
1041 | 1114 | ||
@@ -1045,41 +1118,53 @@ static void frontend_init(struct budget_av *budget_av) | |||
1045 | case SUBID_DVBS_EASYWATCH: | 1118 | case SUBID_DVBS_EASYWATCH: |
1046 | fe = stv0299_attach(&philips_sd1878_config, | 1119 | fe = stv0299_attach(&philips_sd1878_config, |
1047 | &budget_av->budget.i2c_adap); | 1120 | &budget_av->budget.i2c_adap); |
1121 | if (fe) { | ||
1122 | fe->ops.tuner_ops.set_params = philips_sd1878_tda8261_tuner_set_params; | ||
1123 | } | ||
1048 | break; | 1124 | break; |
1049 | 1125 | ||
1050 | case SUBID_DVBS_KNC1_PLUS: | 1126 | case SUBID_DVBS_KNC1_PLUS: |
1051 | case SUBID_DVBS_TYPHOON: | 1127 | case SUBID_DVBS_TYPHOON: |
1052 | fe = stv0299_attach(&typhoon_config, | 1128 | fe = stv0299_attach(&typhoon_config, |
1053 | &budget_av->budget.i2c_adap); | 1129 | &budget_av->budget.i2c_adap); |
1130 | if (fe) { | ||
1131 | fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params; | ||
1132 | } | ||
1054 | break; | 1133 | break; |
1055 | 1134 | ||
1056 | case SUBID_DVBS_CINERGY1200: | 1135 | case SUBID_DVBS_CINERGY1200: |
1057 | fe = stv0299_attach(&cinergy_1200s_config, | 1136 | fe = stv0299_attach(&cinergy_1200s_config, |
1058 | &budget_av->budget.i2c_adap); | 1137 | &budget_av->budget.i2c_adap); |
1138 | if (fe) { | ||
1139 | fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params; | ||
1140 | } | ||
1059 | break; | 1141 | break; |
1060 | 1142 | ||
1061 | case SUBID_DVBC_KNC1: | 1143 | case SUBID_DVBC_KNC1: |
1062 | case SUBID_DVBC_KNC1_PLUS: | 1144 | case SUBID_DVBC_KNC1_PLUS: |
1145 | case SUBID_DVBC_CINERGY1200: | ||
1146 | budget_av->reinitialise_demod = 1; | ||
1063 | fe = tda10021_attach(&philips_cu1216_config, | 1147 | fe = tda10021_attach(&philips_cu1216_config, |
1064 | &budget_av->budget.i2c_adap, | 1148 | &budget_av->budget.i2c_adap, |
1065 | read_pwm(budget_av)); | 1149 | read_pwm(budget_av)); |
1150 | if (fe) { | ||
1151 | budget_av->tda10021_poclkp = 1; | ||
1152 | budget_av->tda10021_set_frontend = fe->ops.set_frontend; | ||
1153 | fe->ops.set_frontend = tda10021_set_frontend; | ||
1154 | fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params; | ||
1155 | } | ||
1066 | break; | 1156 | break; |
1067 | 1157 | ||
1068 | case SUBID_DVBT_KNC1: | 1158 | case SUBID_DVBT_KNC1: |
1069 | case SUBID_DVBT_KNC1_PLUS: | 1159 | case SUBID_DVBT_KNC1_PLUS: |
1070 | fe = tda10046_attach(&philips_tu1216_config, | ||
1071 | &budget_av->budget.i2c_adap); | ||
1072 | break; | ||
1073 | |||
1074 | case SUBID_DVBC_CINERGY1200: | ||
1075 | fe = tda10021_attach(&philips_cu1216_config, | ||
1076 | &budget_av->budget.i2c_adap, | ||
1077 | read_pwm(budget_av)); | ||
1078 | break; | ||
1079 | |||
1080 | case SUBID_DVBT_CINERGY1200: | 1160 | case SUBID_DVBT_CINERGY1200: |
1161 | budget_av->reinitialise_demod = 1; | ||
1081 | fe = tda10046_attach(&philips_tu1216_config, | 1162 | fe = tda10046_attach(&philips_tu1216_config, |
1082 | &budget_av->budget.i2c_adap); | 1163 | &budget_av->budget.i2c_adap); |
1164 | if (fe) { | ||
1165 | fe->ops.tuner_ops.init = philips_tu1216_tuner_init; | ||
1166 | fe->ops.tuner_ops.set_params = philips_tu1216_tuner_set_params; | ||
1167 | } | ||
1083 | break; | 1168 | break; |
1084 | } | 1169 | } |
1085 | 1170 | ||
@@ -1098,8 +1183,8 @@ static void frontend_init(struct budget_av *budget_av) | |||
1098 | if (dvb_register_frontend(&budget_av->budget.dvb_adapter, | 1183 | if (dvb_register_frontend(&budget_av->budget.dvb_adapter, |
1099 | budget_av->budget.dvb_frontend)) { | 1184 | budget_av->budget.dvb_frontend)) { |
1100 | printk(KERN_ERR "budget-av: Frontend registration failed!\n"); | 1185 | printk(KERN_ERR "budget-av: Frontend registration failed!\n"); |
1101 | if (budget_av->budget.dvb_frontend->ops->release) | 1186 | if (budget_av->budget.dvb_frontend->ops.release) |
1102 | budget_av->budget.dvb_frontend->ops->release(budget_av->budget.dvb_frontend); | 1187 | budget_av->budget.dvb_frontend->ops.release(budget_av->budget.dvb_frontend); |
1103 | budget_av->budget.dvb_frontend = NULL; | 1188 | budget_av->budget.dvb_frontend = NULL; |
1104 | } | 1189 | } |
1105 | } | 1190 | } |
@@ -1293,6 +1378,7 @@ MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C); | |||
1293 | MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T); | 1378 | MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T); |
1294 | MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR); | 1379 | MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR); |
1295 | MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR); | 1380 | MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR); |
1381 | MAKE_BUDGET_INFO(satewpls1, "Satelco EasyWatch DVB-S light", BUDGET_KNC1S); | ||
1296 | MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP); | 1382 | MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP); |
1297 | MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP); | 1383 | MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP); |
1298 | MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP); | 1384 | MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP); |
@@ -1309,6 +1395,7 @@ static struct pci_device_id pci_tbl[] = { | |||
1309 | MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014), | 1395 | MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014), |
1310 | MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016), | 1396 | MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016), |
1311 | MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e), | 1397 | MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e), |
1398 | MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a), | ||
1312 | MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020), | 1399 | MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020), |
1313 | MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021), | 1400 | MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021), |
1314 | MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030), | 1401 | MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030), |
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c index e64a609cf4ff..4b966eea3834 100644 --- a/drivers/media/dvb/ttpci/budget-ci.c +++ b/drivers/media/dvb/ttpci/budget-ci.c | |||
@@ -620,10 +620,10 @@ static int philips_su1278_tt_set_symbol_rate(struct dvb_frontend *fe, u32 srate, | |||
620 | return 0; | 620 | return 0; |
621 | } | 621 | } |
622 | 622 | ||
623 | static int philips_su1278_tt_pll_set(struct dvb_frontend *fe, | 623 | static int philips_su1278_tt_tuner_set_params(struct dvb_frontend *fe, |
624 | struct i2c_adapter *i2c, | 624 | struct dvb_frontend_parameters *params) |
625 | struct dvb_frontend_parameters *params) | ||
626 | { | 625 | { |
626 | struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; | ||
627 | u32 div; | 627 | u32 div; |
628 | u8 buf[4]; | 628 | u8 buf[4]; |
629 | struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) }; | 629 | struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) }; |
@@ -649,7 +649,9 @@ static int philips_su1278_tt_pll_set(struct dvb_frontend *fe, | |||
649 | else if (params->frequency < 2150000) | 649 | else if (params->frequency < 2150000) |
650 | buf[3] |= 0xC0; | 650 | buf[3] |= 0xC0; |
651 | 651 | ||
652 | if (i2c_transfer(i2c, &msg, 1) != 1) | 652 | if (fe->ops.i2c_gate_ctrl) |
653 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
654 | if (i2c_transfer(&budget_ci->budget.i2c_adap, &msg, 1) != 1) | ||
653 | return -EIO; | 655 | return -EIO; |
654 | return 0; | 656 | return 0; |
655 | } | 657 | } |
@@ -665,12 +667,11 @@ static struct stv0299_config philips_su1278_tt_config = { | |||
665 | .volt13_op0_op1 = STV0299_VOLT13_OP1, | 667 | .volt13_op0_op1 = STV0299_VOLT13_OP1, |
666 | .min_delay_ms = 50, | 668 | .min_delay_ms = 50, |
667 | .set_symbol_rate = philips_su1278_tt_set_symbol_rate, | 669 | .set_symbol_rate = philips_su1278_tt_set_symbol_rate, |
668 | .pll_set = philips_su1278_tt_pll_set, | ||
669 | }; | 670 | }; |
670 | 671 | ||
671 | 672 | ||
672 | 673 | ||
673 | static int philips_tdm1316l_pll_init(struct dvb_frontend *fe) | 674 | static int philips_tdm1316l_tuner_init(struct dvb_frontend *fe) |
674 | { | 675 | { |
675 | struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; | 676 | struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; |
676 | static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab }; | 677 | static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab }; |
@@ -679,6 +680,8 @@ static int philips_tdm1316l_pll_init(struct dvb_frontend *fe) | |||
679 | sizeof(td1316_init) }; | 680 | sizeof(td1316_init) }; |
680 | 681 | ||
681 | // setup PLL configuration | 682 | // setup PLL configuration |
683 | if (fe->ops.i2c_gate_ctrl) | ||
684 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
682 | if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) | 685 | if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) |
683 | return -EIO; | 686 | return -EIO; |
684 | msleep(1); | 687 | msleep(1); |
@@ -687,14 +690,18 @@ static int philips_tdm1316l_pll_init(struct dvb_frontend *fe) | |||
687 | tuner_msg.addr = 0x65; | 690 | tuner_msg.addr = 0x65; |
688 | tuner_msg.buf = disable_mc44BC374c; | 691 | tuner_msg.buf = disable_mc44BC374c; |
689 | tuner_msg.len = sizeof(disable_mc44BC374c); | 692 | tuner_msg.len = sizeof(disable_mc44BC374c); |
693 | if (fe->ops.i2c_gate_ctrl) | ||
694 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
690 | if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) { | 695 | if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) { |
696 | if (fe->ops.i2c_gate_ctrl) | ||
697 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
691 | i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1); | 698 | i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1); |
692 | } | 699 | } |
693 | 700 | ||
694 | return 0; | 701 | return 0; |
695 | } | 702 | } |
696 | 703 | ||
697 | static int philips_tdm1316l_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | 704 | static int philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) |
698 | { | 705 | { |
699 | struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; | 706 | struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; |
700 | u8 tuner_buf[4]; | 707 | u8 tuner_buf[4]; |
@@ -770,6 +777,8 @@ static int philips_tdm1316l_pll_set(struct dvb_frontend *fe, struct dvb_frontend | |||
770 | tuner_buf[2] = 0xca; | 777 | tuner_buf[2] = 0xca; |
771 | tuner_buf[3] = (cp << 5) | (filter << 3) | band; | 778 | tuner_buf[3] = (cp << 5) | (filter << 3) | band; |
772 | 779 | ||
780 | if (fe->ops.i2c_gate_ctrl) | ||
781 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
773 | if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) | 782 | if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) |
774 | return -EIO; | 783 | return -EIO; |
775 | 784 | ||
@@ -793,13 +802,10 @@ static struct tda1004x_config philips_tdm1316l_config = { | |||
793 | .xtal_freq = TDA10046_XTAL_4M, | 802 | .xtal_freq = TDA10046_XTAL_4M, |
794 | .agc_config = TDA10046_AGC_DEFAULT, | 803 | .agc_config = TDA10046_AGC_DEFAULT, |
795 | .if_freq = TDA10046_FREQ_3617, | 804 | .if_freq = TDA10046_FREQ_3617, |
796 | .pll_init = philips_tdm1316l_pll_init, | ||
797 | .pll_set = philips_tdm1316l_pll_set, | ||
798 | .pll_sleep = NULL, | ||
799 | .request_firmware = philips_tdm1316l_request_firmware, | 805 | .request_firmware = philips_tdm1316l_request_firmware, |
800 | }; | 806 | }; |
801 | 807 | ||
802 | static int dvbc_philips_tdm1316l_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | 808 | static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) |
803 | { | 809 | { |
804 | struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; | 810 | struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; |
805 | u8 tuner_buf[5]; | 811 | u8 tuner_buf[5]; |
@@ -857,13 +863,15 @@ static int dvbc_philips_tdm1316l_pll_set(struct dvb_frontend *fe, struct dvb_fro | |||
857 | tuner_buf[3] = (cp << 5) | (filter << 3) | band; | 863 | tuner_buf[3] = (cp << 5) | (filter << 3) | band; |
858 | tuner_buf[4] = 0x80; | 864 | tuner_buf[4] = 0x80; |
859 | 865 | ||
860 | stv0297_enable_plli2c(fe); | 866 | if (fe->ops.i2c_gate_ctrl) |
867 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
861 | if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) | 868 | if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) |
862 | return -EIO; | 869 | return -EIO; |
863 | 870 | ||
864 | msleep(50); | 871 | msleep(50); |
865 | 872 | ||
866 | stv0297_enable_plli2c(fe); | 873 | if (fe->ops.i2c_gate_ctrl) |
874 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
867 | if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) | 875 | if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) |
868 | return -EIO; | 876 | return -EIO; |
869 | 877 | ||
@@ -969,7 +977,7 @@ static struct stv0297_config dvbc_philips_tdm1316l_config = { | |||
969 | .demod_address = 0x1c, | 977 | .demod_address = 0x1c, |
970 | .inittab = dvbc_philips_tdm1316l_inittab, | 978 | .inittab = dvbc_philips_tdm1316l_inittab, |
971 | .invert = 0, | 979 | .invert = 0, |
972 | .pll_set = dvbc_philips_tdm1316l_pll_set, | 980 | .stop_during_read = 1, |
973 | }; | 981 | }; |
974 | 982 | ||
975 | 983 | ||
@@ -982,6 +990,8 @@ static void frontend_init(struct budget_ci *budget_ci) | |||
982 | budget_ci->budget.dvb_frontend = | 990 | budget_ci->budget.dvb_frontend = |
983 | stv0299_attach(&alps_bsru6_config, &budget_ci->budget.i2c_adap); | 991 | stv0299_attach(&alps_bsru6_config, &budget_ci->budget.i2c_adap); |
984 | if (budget_ci->budget.dvb_frontend) { | 992 | if (budget_ci->budget.dvb_frontend) { |
993 | budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; | ||
994 | budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap; | ||
985 | break; | 995 | break; |
986 | } | 996 | } |
987 | break; | 997 | break; |
@@ -990,6 +1000,7 @@ static void frontend_init(struct budget_ci *budget_ci) | |||
990 | budget_ci->budget.dvb_frontend = | 1000 | budget_ci->budget.dvb_frontend = |
991 | stv0299_attach(&philips_su1278_tt_config, &budget_ci->budget.i2c_adap); | 1001 | stv0299_attach(&philips_su1278_tt_config, &budget_ci->budget.i2c_adap); |
992 | if (budget_ci->budget.dvb_frontend) { | 1002 | if (budget_ci->budget.dvb_frontend) { |
1003 | budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_su1278_tt_tuner_set_params; | ||
993 | break; | 1004 | break; |
994 | } | 1005 | } |
995 | break; | 1006 | break; |
@@ -999,6 +1010,7 @@ static void frontend_init(struct budget_ci *budget_ci) | |||
999 | budget_ci->budget.dvb_frontend = | 1010 | budget_ci->budget.dvb_frontend = |
1000 | stv0297_attach(&dvbc_philips_tdm1316l_config, &budget_ci->budget.i2c_adap); | 1011 | stv0297_attach(&dvbc_philips_tdm1316l_config, &budget_ci->budget.i2c_adap); |
1001 | if (budget_ci->budget.dvb_frontend) { | 1012 | if (budget_ci->budget.dvb_frontend) { |
1013 | budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params; | ||
1002 | break; | 1014 | break; |
1003 | } | 1015 | } |
1004 | break; | 1016 | break; |
@@ -1008,6 +1020,8 @@ static void frontend_init(struct budget_ci *budget_ci) | |||
1008 | budget_ci->budget.dvb_frontend = | 1020 | budget_ci->budget.dvb_frontend = |
1009 | tda10045_attach(&philips_tdm1316l_config, &budget_ci->budget.i2c_adap); | 1021 | tda10045_attach(&philips_tdm1316l_config, &budget_ci->budget.i2c_adap); |
1010 | if (budget_ci->budget.dvb_frontend) { | 1022 | if (budget_ci->budget.dvb_frontend) { |
1023 | budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init; | ||
1024 | budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params; | ||
1011 | break; | 1025 | break; |
1012 | } | 1026 | } |
1013 | break; | 1027 | break; |
@@ -1017,6 +1031,8 @@ static void frontend_init(struct budget_ci *budget_ci) | |||
1017 | budget_ci->budget.dvb_frontend = | 1031 | budget_ci->budget.dvb_frontend = |
1018 | tda10046_attach(&philips_tdm1316l_config, &budget_ci->budget.i2c_adap); | 1032 | tda10046_attach(&philips_tdm1316l_config, &budget_ci->budget.i2c_adap); |
1019 | if (budget_ci->budget.dvb_frontend) { | 1033 | if (budget_ci->budget.dvb_frontend) { |
1034 | budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init; | ||
1035 | budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params; | ||
1020 | break; | 1036 | break; |
1021 | } | 1037 | } |
1022 | break; | 1038 | break; |
@@ -1024,11 +1040,14 @@ static void frontend_init(struct budget_ci *budget_ci) | |||
1024 | case 0x1017: // TT S-1500 PCI | 1040 | case 0x1017: // TT S-1500 PCI |
1025 | budget_ci->budget.dvb_frontend = stv0299_attach(&alps_bsbe1_config, &budget_ci->budget.i2c_adap); | 1041 | budget_ci->budget.dvb_frontend = stv0299_attach(&alps_bsbe1_config, &budget_ci->budget.i2c_adap); |
1026 | if (budget_ci->budget.dvb_frontend) { | 1042 | if (budget_ci->budget.dvb_frontend) { |
1027 | budget_ci->budget.dvb_frontend->ops->dishnetwork_send_legacy_command = NULL; | 1043 | budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params; |
1028 | if (lnbp21_init(budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, LNBP21_LLC, 0)) { | 1044 | budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap; |
1045 | |||
1046 | budget_ci->budget.dvb_frontend->ops.dishnetwork_send_legacy_command = NULL; | ||
1047 | if (lnbp21_attach(budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, LNBP21_LLC, 0)) { | ||
1029 | printk("%s: No LNBP21 found!\n", __FUNCTION__); | 1048 | printk("%s: No LNBP21 found!\n", __FUNCTION__); |
1030 | if (budget_ci->budget.dvb_frontend->ops->release) | 1049 | if (budget_ci->budget.dvb_frontend->ops.release) |
1031 | budget_ci->budget.dvb_frontend->ops->release(budget_ci->budget.dvb_frontend); | 1050 | budget_ci->budget.dvb_frontend->ops.release(budget_ci->budget.dvb_frontend); |
1032 | budget_ci->budget.dvb_frontend = NULL; | 1051 | budget_ci->budget.dvb_frontend = NULL; |
1033 | } | 1052 | } |
1034 | } | 1053 | } |
@@ -1046,8 +1065,8 @@ static void frontend_init(struct budget_ci *budget_ci) | |||
1046 | if (dvb_register_frontend | 1065 | if (dvb_register_frontend |
1047 | (&budget_ci->budget.dvb_adapter, budget_ci->budget.dvb_frontend)) { | 1066 | (&budget_ci->budget.dvb_adapter, budget_ci->budget.dvb_frontend)) { |
1048 | printk("budget-ci: Frontend registration failed!\n"); | 1067 | printk("budget-ci: Frontend registration failed!\n"); |
1049 | if (budget_ci->budget.dvb_frontend->ops->release) | 1068 | if (budget_ci->budget.dvb_frontend->ops.release) |
1050 | budget_ci->budget.dvb_frontend->ops->release(budget_ci->budget.dvb_frontend); | 1069 | budget_ci->budget.dvb_frontend->ops.release(budget_ci->budget.dvb_frontend); |
1051 | budget_ci->budget.dvb_frontend = NULL; | 1070 | budget_ci->budget.dvb_frontend = NULL; |
1052 | } | 1071 | } |
1053 | } | 1072 | } |
diff --git a/drivers/media/dvb/ttpci/budget-core.c b/drivers/media/dvb/ttpci/budget-core.c index ea2066d461fc..e4cf7775e07f 100644 --- a/drivers/media/dvb/ttpci/budget-core.c +++ b/drivers/media/dvb/ttpci/budget-core.c | |||
@@ -400,7 +400,9 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, | |||
400 | budget->dev->name, budget->buffer_width, budget->buffer_height); | 400 | budget->dev->name, budget->buffer_width, budget->buffer_height); |
401 | printk("%s: dma buffer size %u\n", budget->dev->name, budget->buffer_size); | 401 | printk("%s: dma buffer size %u\n", budget->dev->name, budget->buffer_size); |
402 | 402 | ||
403 | dvb_register_adapter(&budget->dvb_adapter, budget->card->name, owner); | 403 | if ((ret = dvb_register_adapter(&budget->dvb_adapter, budget->card->name, owner, &budget->dev->pci->dev)) < 0) { |
404 | return ret; | ||
405 | } | ||
404 | 406 | ||
405 | /* set dd1 stream a & b */ | 407 | /* set dd1 stream a & b */ |
406 | saa7146_write(dev, DD1_STREAM_B, 0x00000000); | 408 | saa7146_write(dev, DD1_STREAM_B, 0x00000000); |
diff --git a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/dvb/ttpci/budget-patch.c index 1b3aaac5e763..ee60ce90a400 100644 --- a/drivers/media/dvb/ttpci/budget-patch.c +++ b/drivers/media/dvb/ttpci/budget-patch.c | |||
@@ -258,7 +258,7 @@ static int budget_patch_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_c | |||
258 | return 0; | 258 | return 0; |
259 | } | 259 | } |
260 | 260 | ||
261 | static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 261 | static int alps_bsrv2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) |
262 | { | 262 | { |
263 | struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv; | 263 | struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv; |
264 | u8 pwr = 0; | 264 | u8 pwr = 0; |
@@ -281,7 +281,10 @@ static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_param | |||
281 | // NOTE: since we're using a prescaler of 2, we set the | 281 | // NOTE: since we're using a prescaler of 2, we set the |
282 | // divisor frequency to 62.5kHz and divide by 125 above | 282 | // divisor frequency to 62.5kHz and divide by 125 above |
283 | 283 | ||
284 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; | 284 | if (fe->ops.i2c_gate_ctrl) |
285 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
286 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) | ||
287 | return -EIO; | ||
285 | return 0; | 288 | return 0; |
286 | } | 289 | } |
287 | 290 | ||
@@ -289,10 +292,9 @@ static struct ves1x93_config alps_bsrv2_config = { | |||
289 | .demod_address = 0x08, | 292 | .demod_address = 0x08, |
290 | .xin = 90100000UL, | 293 | .xin = 90100000UL, |
291 | .invert_pwm = 0, | 294 | .invert_pwm = 0, |
292 | .pll_set = alps_bsrv2_pll_set, | ||
293 | }; | 295 | }; |
294 | 296 | ||
295 | static int grundig_29504_451_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 297 | static int grundig_29504_451_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) |
296 | { | 298 | { |
297 | struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv; | 299 | struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv; |
298 | u32 div; | 300 | u32 div; |
@@ -305,13 +307,15 @@ static int grundig_29504_451_pll_set(struct dvb_frontend* fe, struct dvb_fronten | |||
305 | data[2] = 0x8e; | 307 | data[2] = 0x8e; |
306 | data[3] = 0x00; | 308 | data[3] = 0x00; |
307 | 309 | ||
308 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; | 310 | if (fe->ops.i2c_gate_ctrl) |
311 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
312 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) | ||
313 | return -EIO; | ||
309 | return 0; | 314 | return 0; |
310 | } | 315 | } |
311 | 316 | ||
312 | static struct tda8083_config grundig_29504_451_config = { | 317 | static struct tda8083_config grundig_29504_451_config = { |
313 | .demod_address = 0x68, | 318 | .demod_address = 0x68, |
314 | .pll_set = grundig_29504_451_pll_set, | ||
315 | }; | 319 | }; |
316 | 320 | ||
317 | static void frontend_init(struct budget_patch* budget) | 321 | static void frontend_init(struct budget_patch* budget) |
@@ -323,27 +327,32 @@ static void frontend_init(struct budget_patch* budget) | |||
323 | // try the ALPS BSRV2 first of all | 327 | // try the ALPS BSRV2 first of all |
324 | budget->dvb_frontend = ves1x93_attach(&alps_bsrv2_config, &budget->i2c_adap); | 328 | budget->dvb_frontend = ves1x93_attach(&alps_bsrv2_config, &budget->i2c_adap); |
325 | if (budget->dvb_frontend) { | 329 | if (budget->dvb_frontend) { |
326 | budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_patch_diseqc_send_master_cmd; | 330 | budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params; |
327 | budget->dvb_frontend->ops->diseqc_send_burst = budget_patch_diseqc_send_burst; | 331 | budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_patch_diseqc_send_master_cmd; |
328 | budget->dvb_frontend->ops->set_tone = budget_patch_set_tone; | 332 | budget->dvb_frontend->ops.diseqc_send_burst = budget_patch_diseqc_send_burst; |
333 | budget->dvb_frontend->ops.set_tone = budget_patch_set_tone; | ||
329 | break; | 334 | break; |
330 | } | 335 | } |
331 | 336 | ||
332 | // try the ALPS BSRU6 now | 337 | // try the ALPS BSRU6 now |
333 | budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap); | 338 | budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap); |
334 | if (budget->dvb_frontend) { | 339 | if (budget->dvb_frontend) { |
335 | budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_diseqc_send_master_cmd; | 340 | budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; |
336 | budget->dvb_frontend->ops->diseqc_send_burst = budget_diseqc_send_burst; | 341 | budget->dvb_frontend->tuner_priv = &budget->i2c_adap; |
337 | budget->dvb_frontend->ops->set_tone = budget_set_tone; | 342 | |
343 | budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd; | ||
344 | budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst; | ||
345 | budget->dvb_frontend->ops.set_tone = budget_set_tone; | ||
338 | break; | 346 | break; |
339 | } | 347 | } |
340 | 348 | ||
341 | // Try the grundig 29504-451 | 349 | // Try the grundig 29504-451 |
342 | budget->dvb_frontend = tda8083_attach(&grundig_29504_451_config, &budget->i2c_adap); | 350 | budget->dvb_frontend = tda8083_attach(&grundig_29504_451_config, &budget->i2c_adap); |
343 | if (budget->dvb_frontend) { | 351 | if (budget->dvb_frontend) { |
344 | budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_diseqc_send_master_cmd; | 352 | budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params; |
345 | budget->dvb_frontend->ops->diseqc_send_burst = budget_diseqc_send_burst; | 353 | budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd; |
346 | budget->dvb_frontend->ops->set_tone = budget_set_tone; | 354 | budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst; |
355 | budget->dvb_frontend->ops.set_tone = budget_set_tone; | ||
347 | break; | 356 | break; |
348 | } | 357 | } |
349 | break; | 358 | break; |
@@ -358,8 +367,8 @@ static void frontend_init(struct budget_patch* budget) | |||
358 | } else { | 367 | } else { |
359 | if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend)) { | 368 | if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend)) { |
360 | printk("budget-av: Frontend registration failed!\n"); | 369 | printk("budget-av: Frontend registration failed!\n"); |
361 | if (budget->dvb_frontend->ops->release) | 370 | if (budget->dvb_frontend->ops.release) |
362 | budget->dvb_frontend->ops->release(budget->dvb_frontend); | 371 | budget->dvb_frontend->ops.release(budget->dvb_frontend); |
363 | budget->dvb_frontend = NULL; | 372 | budget->dvb_frontend = NULL; |
364 | } | 373 | } |
365 | } | 374 | } |
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c index c23c02d95641..35761f13c12b 100644 --- a/drivers/media/dvb/ttpci/budget.c +++ b/drivers/media/dvb/ttpci/budget.c | |||
@@ -186,7 +186,7 @@ static int budget_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t m | |||
186 | return 0; | 186 | return 0; |
187 | } | 187 | } |
188 | 188 | ||
189 | static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 189 | static int alps_bsrv2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) |
190 | { | 190 | { |
191 | struct budget* budget = (struct budget*) fe->dvb->priv; | 191 | struct budget* budget = (struct budget*) fe->dvb->priv; |
192 | u8 pwr = 0; | 192 | u8 pwr = 0; |
@@ -209,6 +209,8 @@ static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_param | |||
209 | // NOTE: since we're using a prescaler of 2, we set the | 209 | // NOTE: since we're using a prescaler of 2, we set the |
210 | // divisor frequency to 62.5kHz and divide by 125 above | 210 | // divisor frequency to 62.5kHz and divide by 125 above |
211 | 211 | ||
212 | if (fe->ops.i2c_gate_ctrl) | ||
213 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
212 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; | 214 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; |
213 | return 0; | 215 | return 0; |
214 | } | 216 | } |
@@ -218,10 +220,9 @@ static struct ves1x93_config alps_bsrv2_config = | |||
218 | .demod_address = 0x08, | 220 | .demod_address = 0x08, |
219 | .xin = 90100000UL, | 221 | .xin = 90100000UL, |
220 | .invert_pwm = 0, | 222 | .invert_pwm = 0, |
221 | .pll_set = alps_bsrv2_pll_set, | ||
222 | }; | 223 | }; |
223 | 224 | ||
224 | static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 225 | static int alps_tdbe2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) |
225 | { | 226 | { |
226 | struct budget* budget = (struct budget*) fe->dvb->priv; | 227 | struct budget* budget = (struct budget*) fe->dvb->priv; |
227 | u32 div; | 228 | u32 div; |
@@ -235,6 +236,8 @@ static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_param | |||
235 | data[2] = 0x85 | ((div >> 10) & 0x60); | 236 | data[2] = 0x85 | ((div >> 10) & 0x60); |
236 | data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81); | 237 | data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81); |
237 | 238 | ||
239 | if (fe->ops.i2c_gate_ctrl) | ||
240 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
238 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; | 241 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; |
239 | return 0; | 242 | return 0; |
240 | } | 243 | } |
@@ -244,10 +247,9 @@ static struct ves1820_config alps_tdbe2_config = { | |||
244 | .xin = 57840000UL, | 247 | .xin = 57840000UL, |
245 | .invert = 1, | 248 | .invert = 1, |
246 | .selagc = VES1820_SELAGC_SIGNAMPERR, | 249 | .selagc = VES1820_SELAGC_SIGNAMPERR, |
247 | .pll_set = alps_tdbe2_pll_set, | ||
248 | }; | 250 | }; |
249 | 251 | ||
250 | static int grundig_29504_401_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 252 | static int grundig_29504_401_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) |
251 | { | 253 | { |
252 | struct budget* budget = (struct budget*) fe->dvb->priv; | 254 | struct budget* budget = (struct budget*) fe->dvb->priv; |
253 | u32 div; | 255 | u32 div; |
@@ -274,16 +276,17 @@ static int grundig_29504_401_pll_set(struct dvb_frontend* fe, struct dvb_fronten | |||
274 | data[2] = ((div >> 10) & 0x60) | cfg; | 276 | data[2] = ((div >> 10) & 0x60) | cfg; |
275 | data[3] = (cpump << 6) | band_select; | 277 | data[3] = (cpump << 6) | band_select; |
276 | 278 | ||
279 | if (fe->ops.i2c_gate_ctrl) | ||
280 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
277 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; | 281 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; |
278 | return 0; | 282 | return 0; |
279 | } | 283 | } |
280 | 284 | ||
281 | static struct l64781_config grundig_29504_401_config = { | 285 | static struct l64781_config grundig_29504_401_config = { |
282 | .demod_address = 0x55, | 286 | .demod_address = 0x55, |
283 | .pll_set = grundig_29504_401_pll_set, | ||
284 | }; | 287 | }; |
285 | 288 | ||
286 | static int grundig_29504_451_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 289 | static int grundig_29504_451_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) |
287 | { | 290 | { |
288 | struct budget* budget = (struct budget*) fe->dvb->priv; | 291 | struct budget* budget = (struct budget*) fe->dvb->priv; |
289 | u32 div; | 292 | u32 div; |
@@ -296,16 +299,17 @@ static int grundig_29504_451_pll_set(struct dvb_frontend* fe, struct dvb_fronten | |||
296 | data[2] = 0x8e; | 299 | data[2] = 0x8e; |
297 | data[3] = 0x00; | 300 | data[3] = 0x00; |
298 | 301 | ||
302 | if (fe->ops.i2c_gate_ctrl) | ||
303 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
299 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; | 304 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; |
300 | return 0; | 305 | return 0; |
301 | } | 306 | } |
302 | 307 | ||
303 | static struct tda8083_config grundig_29504_451_config = { | 308 | static struct tda8083_config grundig_29504_451_config = { |
304 | .demod_address = 0x68, | 309 | .demod_address = 0x68, |
305 | .pll_set = grundig_29504_451_pll_set, | ||
306 | }; | 310 | }; |
307 | 311 | ||
308 | static int s5h1420_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u32* freqout) | 312 | static int s5h1420_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) |
309 | { | 313 | { |
310 | struct budget* budget = (struct budget*) fe->dvb->priv; | 314 | struct budget* budget = (struct budget*) fe->dvb->priv; |
311 | u32 div; | 315 | u32 div; |
@@ -326,16 +330,16 @@ static int s5h1420_pll_set(struct dvb_frontend* fe, struct dvb_frontend_paramete | |||
326 | else | 330 | else |
327 | data[3] = 0xc0; | 331 | data[3] = 0xc0; |
328 | 332 | ||
333 | if (fe->ops.i2c_gate_ctrl) | ||
334 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
329 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; | 335 | if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; |
330 | 336 | ||
331 | *freqout = div * 1000; | ||
332 | return 0; | 337 | return 0; |
333 | } | 338 | } |
334 | 339 | ||
335 | static struct s5h1420_config s5h1420_config = { | 340 | static struct s5h1420_config s5h1420_config = { |
336 | .demod_address = 0x53, | 341 | .demod_address = 0x53, |
337 | .invert = 1, | 342 | .invert = 1, |
338 | .pll_set = s5h1420_pll_set, | ||
339 | }; | 343 | }; |
340 | 344 | ||
341 | static u8 read_pwm(struct budget* budget) | 345 | static u8 read_pwm(struct budget* budget) |
@@ -359,18 +363,21 @@ static void frontend_init(struct budget *budget) | |||
359 | // try the ALPS BSRV2 first of all | 363 | // try the ALPS BSRV2 first of all |
360 | budget->dvb_frontend = ves1x93_attach(&alps_bsrv2_config, &budget->i2c_adap); | 364 | budget->dvb_frontend = ves1x93_attach(&alps_bsrv2_config, &budget->i2c_adap); |
361 | if (budget->dvb_frontend) { | 365 | if (budget->dvb_frontend) { |
362 | budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_diseqc_send_master_cmd; | 366 | budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params; |
363 | budget->dvb_frontend->ops->diseqc_send_burst = budget_diseqc_send_burst; | 367 | budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd; |
364 | budget->dvb_frontend->ops->set_tone = budget_set_tone; | 368 | budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst; |
369 | budget->dvb_frontend->ops.set_tone = budget_set_tone; | ||
365 | break; | 370 | break; |
366 | } | 371 | } |
367 | 372 | ||
368 | // try the ALPS BSRU6 now | 373 | // try the ALPS BSRU6 now |
369 | budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap); | 374 | budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap); |
370 | if (budget->dvb_frontend) { | 375 | if (budget->dvb_frontend) { |
371 | budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_diseqc_send_master_cmd; | 376 | budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; |
372 | budget->dvb_frontend->ops->diseqc_send_burst = budget_diseqc_send_burst; | 377 | budget->dvb_frontend->tuner_priv = &budget->i2c_adap; |
373 | budget->dvb_frontend->ops->set_tone = budget_set_tone; | 378 | budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd; |
379 | budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst; | ||
380 | budget->dvb_frontend->ops.set_tone = budget_set_tone; | ||
374 | break; | 381 | break; |
375 | } | 382 | } |
376 | break; | 383 | break; |
@@ -378,35 +385,45 @@ static void frontend_init(struct budget *budget) | |||
378 | case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659)) | 385 | case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659)) |
379 | 386 | ||
380 | budget->dvb_frontend = ves1820_attach(&alps_tdbe2_config, &budget->i2c_adap, read_pwm(budget)); | 387 | budget->dvb_frontend = ves1820_attach(&alps_tdbe2_config, &budget->i2c_adap, read_pwm(budget)); |
381 | if (budget->dvb_frontend) break; | 388 | if (budget->dvb_frontend) { |
389 | budget->dvb_frontend->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params; | ||
390 | break; | ||
391 | } | ||
382 | break; | 392 | break; |
383 | 393 | ||
384 | case 0x1005: // Hauppauge/TT Nova-T budget (L64781/Grundig 29504-401(tsa5060)) | 394 | case 0x1005: // Hauppauge/TT Nova-T budget (L64781/Grundig 29504-401(tsa5060)) |
385 | 395 | ||
386 | budget->dvb_frontend = l64781_attach(&grundig_29504_401_config, &budget->i2c_adap); | 396 | budget->dvb_frontend = l64781_attach(&grundig_29504_401_config, &budget->i2c_adap); |
387 | if (budget->dvb_frontend) break; | 397 | if (budget->dvb_frontend) { |
398 | budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params; | ||
399 | break; | ||
400 | } | ||
388 | break; | 401 | break; |
389 | 402 | ||
390 | case 0x4f60: // Fujitsu Siemens Activy Budget-S PCI rev AL (stv0299/ALPS BSRU6(tsa5059)) | 403 | case 0x4f60: // Fujitsu Siemens Activy Budget-S PCI rev AL (stv0299/ALPS BSRU6(tsa5059)) |
391 | budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap); | 404 | budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap); |
392 | if (budget->dvb_frontend) { | 405 | if (budget->dvb_frontend) { |
393 | budget->dvb_frontend->ops->set_voltage = siemens_budget_set_voltage; | 406 | budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; |
394 | budget->dvb_frontend->ops->dishnetwork_send_legacy_command = NULL; | 407 | budget->dvb_frontend->tuner_priv = &budget->i2c_adap; |
408 | budget->dvb_frontend->ops.set_voltage = siemens_budget_set_voltage; | ||
409 | budget->dvb_frontend->ops.dishnetwork_send_legacy_command = NULL; | ||
395 | } | 410 | } |
396 | break; | 411 | break; |
397 | 412 | ||
398 | case 0x4f61: // Fujitsu Siemens Activy Budget-S PCI rev GR (tda8083/Grundig 29504-451(tsa5522)) | 413 | case 0x4f61: // Fujitsu Siemens Activy Budget-S PCI rev GR (tda8083/Grundig 29504-451(tsa5522)) |
399 | budget->dvb_frontend = tda8083_attach(&grundig_29504_451_config, &budget->i2c_adap); | 414 | budget->dvb_frontend = tda8083_attach(&grundig_29504_451_config, &budget->i2c_adap); |
400 | if (budget->dvb_frontend) { | 415 | if (budget->dvb_frontend) { |
401 | budget->dvb_frontend->ops->set_voltage = siemens_budget_set_voltage; | 416 | budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params; |
402 | budget->dvb_frontend->ops->dishnetwork_send_legacy_command = NULL; | 417 | budget->dvb_frontend->ops.set_voltage = siemens_budget_set_voltage; |
418 | budget->dvb_frontend->ops.dishnetwork_send_legacy_command = NULL; | ||
403 | } | 419 | } |
404 | break; | 420 | break; |
405 | 421 | ||
406 | case 0x1016: // Hauppauge/TT Nova-S SE (samsung s5h1420/????(tda8260)) | 422 | case 0x1016: // Hauppauge/TT Nova-S SE (samsung s5h1420/????(tda8260)) |
407 | budget->dvb_frontend = s5h1420_attach(&s5h1420_config, &budget->i2c_adap); | 423 | budget->dvb_frontend = s5h1420_attach(&s5h1420_config, &budget->i2c_adap); |
408 | if (budget->dvb_frontend) { | 424 | if (budget->dvb_frontend) { |
409 | if (lnbp21_init(budget->dvb_frontend, &budget->i2c_adap, 0, 0)) { | 425 | budget->dvb_frontend->ops.tuner_ops.set_params = s5h1420_tuner_set_params; |
426 | if (lnbp21_attach(budget->dvb_frontend, &budget->i2c_adap, 0, 0)) { | ||
410 | printk("%s: No LNBP21 found!\n", __FUNCTION__); | 427 | printk("%s: No LNBP21 found!\n", __FUNCTION__); |
411 | goto error_out; | 428 | goto error_out; |
412 | } | 429 | } |
@@ -428,8 +445,8 @@ static void frontend_init(struct budget *budget) | |||
428 | 445 | ||
429 | error_out: | 446 | error_out: |
430 | printk("budget: Frontend registration failed!\n"); | 447 | printk("budget: Frontend registration failed!\n"); |
431 | if (budget->dvb_frontend->ops->release) | 448 | if (budget->dvb_frontend->ops.release) |
432 | budget->dvb_frontend->ops->release(budget->dvb_frontend); | 449 | budget->dvb_frontend->ops.release(budget->dvb_frontend); |
433 | budget->dvb_frontend = NULL; | 450 | budget->dvb_frontend = NULL; |
434 | return; | 451 | return; |
435 | } | 452 | } |
diff --git a/drivers/media/dvb/ttusb-budget/Kconfig b/drivers/media/dvb/ttusb-budget/Kconfig index 914587d52b57..92c7cdcf8981 100644 --- a/drivers/media/dvb/ttusb-budget/Kconfig +++ b/drivers/media/dvb/ttusb-budget/Kconfig | |||
@@ -6,6 +6,8 @@ config DVB_TTUSB_BUDGET | |||
6 | select DVB_VES1820 | 6 | select DVB_VES1820 |
7 | select DVB_TDA8083 | 7 | select DVB_TDA8083 |
8 | select DVB_STV0299 | 8 | select DVB_STV0299 |
9 | select DVB_STV0297 | ||
10 | select DVB_LNBP21 | ||
9 | help | 11 | help |
10 | Support for external USB adapters designed by Technotrend and | 12 | Support for external USB adapters designed by Technotrend and |
11 | produced by Hauppauge, shipped under the brand name 'Nova-USB'. | 13 | produced by Hauppauge, shipped under the brand name 'Nova-USB'. |
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c index 6ceae38125c7..14559ef6153c 100644 --- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c +++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c | |||
@@ -30,6 +30,8 @@ | |||
30 | #include "tda1004x.h" | 30 | #include "tda1004x.h" |
31 | #include "stv0299.h" | 31 | #include "stv0299.h" |
32 | #include "tda8083.h" | 32 | #include "tda8083.h" |
33 | #include "stv0297.h" | ||
34 | #include "lnbp21.h" | ||
33 | 35 | ||
34 | #include <linux/dvb/frontend.h> | 36 | #include <linux/dvb/frontend.h> |
35 | #include <linux/dvb/dmx.h> | 37 | #include <linux/dvb/dmx.h> |
@@ -486,31 +488,6 @@ static int ttusb_send_diseqc(struct dvb_frontend* fe, | |||
486 | } | 488 | } |
487 | #endif | 489 | #endif |
488 | 490 | ||
489 | static int lnbp21_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) | ||
490 | { | ||
491 | struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; | ||
492 | int ret; | ||
493 | u8 data[1]; | ||
494 | struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = data, .len = sizeof(data) }; | ||
495 | |||
496 | switch(voltage) { | ||
497 | case SEC_VOLTAGE_OFF: | ||
498 | data[0] = 0x00; | ||
499 | break; | ||
500 | case SEC_VOLTAGE_13: | ||
501 | data[0] = 0x44; | ||
502 | break; | ||
503 | case SEC_VOLTAGE_18: | ||
504 | data[0] = 0x4c; | ||
505 | break; | ||
506 | default: | ||
507 | return -EINVAL; | ||
508 | }; | ||
509 | |||
510 | ret = i2c_transfer(&ttusb->i2c_adap, &msg, 1); | ||
511 | return (ret != 1) ? -EIO : 0; | ||
512 | } | ||
513 | |||
514 | static int ttusb_update_lnb(struct ttusb *ttusb) | 491 | static int ttusb_update_lnb(struct ttusb *ttusb) |
515 | { | 492 | { |
516 | u8 b[] = { 0xaa, ++ttusb->c, 0x16, 5, /*power: */ 1, | 493 | u8 b[] = { 0xaa, ++ttusb->c, 0x16, 5, /*power: */ 1, |
@@ -1048,7 +1025,7 @@ static u32 functionality(struct i2c_adapter *adapter) | |||
1048 | 1025 | ||
1049 | 1026 | ||
1050 | 1027 | ||
1051 | static int alps_tdmb7_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 1028 | static int alps_tdmb7_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) |
1052 | { | 1029 | { |
1053 | struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; | 1030 | struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; |
1054 | u8 data[4]; | 1031 | u8 data[4]; |
@@ -1062,20 +1039,21 @@ static int alps_tdmb7_pll_set(struct dvb_frontend* fe, struct dvb_frontend_param | |||
1062 | data[2] = ((div >> 10) & 0x60) | 0x85; | 1039 | data[2] = ((div >> 10) & 0x60) | 0x85; |
1063 | data[3] = params->frequency < 592000000 ? 0x40 : 0x80; | 1040 | data[3] = params->frequency < 592000000 ? 0x40 : 0x80; |
1064 | 1041 | ||
1042 | if (fe->ops.i2c_gate_ctrl) | ||
1043 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1065 | if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1) return -EIO; | 1044 | if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1) return -EIO; |
1066 | return 0; | 1045 | return 0; |
1067 | } | 1046 | } |
1068 | 1047 | ||
1069 | static struct cx22700_config alps_tdmb7_config = { | 1048 | static struct cx22700_config alps_tdmb7_config = { |
1070 | .demod_address = 0x43, | 1049 | .demod_address = 0x43, |
1071 | .pll_set = alps_tdmb7_pll_set, | ||
1072 | }; | 1050 | }; |
1073 | 1051 | ||
1074 | 1052 | ||
1075 | 1053 | ||
1076 | 1054 | ||
1077 | 1055 | ||
1078 | static int philips_tdm1316l_pll_init(struct dvb_frontend* fe) | 1056 | static int philips_tdm1316l_tuner_init(struct dvb_frontend* fe) |
1079 | { | 1057 | { |
1080 | struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; | 1058 | struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; |
1081 | static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab }; | 1059 | static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab }; |
@@ -1083,6 +1061,8 @@ static int philips_tdm1316l_pll_init(struct dvb_frontend* fe) | |||
1083 | struct i2c_msg tuner_msg = { .addr=0x60, .flags=0, .buf=td1316_init, .len=sizeof(td1316_init) }; | 1061 | struct i2c_msg tuner_msg = { .addr=0x60, .flags=0, .buf=td1316_init, .len=sizeof(td1316_init) }; |
1084 | 1062 | ||
1085 | // setup PLL configuration | 1063 | // setup PLL configuration |
1064 | if (fe->ops.i2c_gate_ctrl) | ||
1065 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1086 | if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) return -EIO; | 1066 | if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) return -EIO; |
1087 | msleep(1); | 1067 | msleep(1); |
1088 | 1068 | ||
@@ -1090,6 +1070,8 @@ static int philips_tdm1316l_pll_init(struct dvb_frontend* fe) | |||
1090 | tuner_msg.addr = 0x65; | 1070 | tuner_msg.addr = 0x65; |
1091 | tuner_msg.buf = disable_mc44BC374c; | 1071 | tuner_msg.buf = disable_mc44BC374c; |
1092 | tuner_msg.len = sizeof(disable_mc44BC374c); | 1072 | tuner_msg.len = sizeof(disable_mc44BC374c); |
1073 | if (fe->ops.i2c_gate_ctrl) | ||
1074 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1093 | if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) { | 1075 | if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) { |
1094 | i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1); | 1076 | i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1); |
1095 | } | 1077 | } |
@@ -1097,7 +1079,7 @@ static int philips_tdm1316l_pll_init(struct dvb_frontend* fe) | |||
1097 | return 0; | 1079 | return 0; |
1098 | } | 1080 | } |
1099 | 1081 | ||
1100 | static int philips_tdm1316l_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 1082 | static int philips_tdm1316l_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) |
1101 | { | 1083 | { |
1102 | struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; | 1084 | struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; |
1103 | u8 tuner_buf[4]; | 1085 | u8 tuner_buf[4]; |
@@ -1157,6 +1139,8 @@ static int philips_tdm1316l_pll_set(struct dvb_frontend* fe, struct dvb_frontend | |||
1157 | tuner_buf[2] = 0xca; | 1139 | tuner_buf[2] = 0xca; |
1158 | tuner_buf[3] = (cp << 5) | (filter << 3) | band; | 1140 | tuner_buf[3] = (cp << 5) | (filter << 3) | band; |
1159 | 1141 | ||
1142 | if (fe->ops.i2c_gate_ctrl) | ||
1143 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1160 | if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) | 1144 | if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) |
1161 | return -EIO; | 1145 | return -EIO; |
1162 | 1146 | ||
@@ -1176,8 +1160,6 @@ static struct tda1004x_config philips_tdm1316l_config = { | |||
1176 | .demod_address = 0x8, | 1160 | .demod_address = 0x8, |
1177 | .invert = 1, | 1161 | .invert = 1, |
1178 | .invert_oclk = 0, | 1162 | .invert_oclk = 0, |
1179 | .pll_init = philips_tdm1316l_pll_init, | ||
1180 | .pll_set = philips_tdm1316l_pll_set, | ||
1181 | .request_firmware = philips_tdm1316l_request_firmware, | 1163 | .request_firmware = philips_tdm1316l_request_firmware, |
1182 | }; | 1164 | }; |
1183 | 1165 | ||
@@ -1299,7 +1281,7 @@ static int alps_stv0299_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 | |||
1299 | return 0; | 1281 | return 0; |
1300 | } | 1282 | } |
1301 | 1283 | ||
1302 | static int philips_tsa5059_pll_set(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters *params) | 1284 | static int philips_tsa5059_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) |
1303 | { | 1285 | { |
1304 | struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; | 1286 | struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; |
1305 | u8 buf[4]; | 1287 | u8 buf[4]; |
@@ -1322,7 +1304,9 @@ static int philips_tsa5059_pll_set(struct dvb_frontend *fe, struct i2c_adapter * | |||
1322 | if (ttusb->revision == TTUSB_REV_2_2) | 1304 | if (ttusb->revision == TTUSB_REV_2_2) |
1323 | buf[3] |= 0x20; | 1305 | buf[3] |= 0x20; |
1324 | 1306 | ||
1325 | if (i2c_transfer(i2c, &msg, 1) != 1) | 1307 | if (fe->ops.i2c_gate_ctrl) |
1308 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1309 | if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1) | ||
1326 | return -EIO; | 1310 | return -EIO; |
1327 | 1311 | ||
1328 | return 0; | 1312 | return 0; |
@@ -1338,10 +1322,9 @@ static struct stv0299_config alps_stv0299_config = { | |||
1338 | .volt13_op0_op1 = STV0299_VOLT13_OP1, | 1322 | .volt13_op0_op1 = STV0299_VOLT13_OP1, |
1339 | .min_delay_ms = 100, | 1323 | .min_delay_ms = 100, |
1340 | .set_symbol_rate = alps_stv0299_set_symbol_rate, | 1324 | .set_symbol_rate = alps_stv0299_set_symbol_rate, |
1341 | .pll_set = philips_tsa5059_pll_set, | ||
1342 | }; | 1325 | }; |
1343 | 1326 | ||
1344 | static int ttusb_novas_grundig_29504_491_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | 1327 | static int ttusb_novas_grundig_29504_491_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) |
1345 | { | 1328 | { |
1346 | struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; | 1329 | struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; |
1347 | u8 buf[4]; | 1330 | u8 buf[4]; |
@@ -1355,6 +1338,8 @@ static int ttusb_novas_grundig_29504_491_pll_set(struct dvb_frontend *fe, struct | |||
1355 | buf[2] = 0x8e; | 1338 | buf[2] = 0x8e; |
1356 | buf[3] = 0x00; | 1339 | buf[3] = 0x00; |
1357 | 1340 | ||
1341 | if (fe->ops.i2c_gate_ctrl) | ||
1342 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1358 | if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1) | 1343 | if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1) |
1359 | return -EIO; | 1344 | return -EIO; |
1360 | 1345 | ||
@@ -1364,10 +1349,9 @@ static int ttusb_novas_grundig_29504_491_pll_set(struct dvb_frontend *fe, struct | |||
1364 | static struct tda8083_config ttusb_novas_grundig_29504_491_config = { | 1349 | static struct tda8083_config ttusb_novas_grundig_29504_491_config = { |
1365 | 1350 | ||
1366 | .demod_address = 0x68, | 1351 | .demod_address = 0x68, |
1367 | .pll_set = ttusb_novas_grundig_29504_491_pll_set, | ||
1368 | }; | 1352 | }; |
1369 | 1353 | ||
1370 | static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 1354 | static int alps_tdbe2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) |
1371 | { | 1355 | { |
1372 | struct ttusb* ttusb = fe->dvb->priv; | 1356 | struct ttusb* ttusb = fe->dvb->priv; |
1373 | u32 div; | 1357 | u32 div; |
@@ -1381,6 +1365,8 @@ static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_param | |||
1381 | data[2] = 0x85 | ((div >> 10) & 0x60); | 1365 | data[2] = 0x85 | ((div >> 10) & 0x60); |
1382 | data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81); | 1366 | data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81); |
1383 | 1367 | ||
1368 | if (fe->ops.i2c_gate_ctrl) | ||
1369 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1384 | if (i2c_transfer (&ttusb->i2c_adap, &msg, 1) != 1) | 1370 | if (i2c_transfer (&ttusb->i2c_adap, &msg, 1) != 1) |
1385 | return -EIO; | 1371 | return -EIO; |
1386 | 1372 | ||
@@ -1393,7 +1379,6 @@ static struct ves1820_config alps_tdbe2_config = { | |||
1393 | .xin = 57840000UL, | 1379 | .xin = 57840000UL, |
1394 | .invert = 1, | 1380 | .invert = 1, |
1395 | .selagc = VES1820_SELAGC_SIGNAMPERR, | 1381 | .selagc = VES1820_SELAGC_SIGNAMPERR, |
1396 | .pll_set = alps_tdbe2_pll_set, | ||
1397 | }; | 1382 | }; |
1398 | 1383 | ||
1399 | static u8 read_pwm(struct ttusb* ttusb) | 1384 | static u8 read_pwm(struct ttusb* ttusb) |
@@ -1410,6 +1395,174 @@ static u8 read_pwm(struct ttusb* ttusb) | |||
1410 | } | 1395 | } |
1411 | 1396 | ||
1412 | 1397 | ||
1398 | static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | ||
1399 | { | ||
1400 | struct ttusb *ttusb = (struct ttusb *) fe->dvb->priv; | ||
1401 | u8 tuner_buf[5]; | ||
1402 | struct i2c_msg tuner_msg = {.addr = 0x60, | ||
1403 | .flags = 0, | ||
1404 | .buf = tuner_buf, | ||
1405 | .len = sizeof(tuner_buf) }; | ||
1406 | int tuner_frequency = 0; | ||
1407 | u8 band, cp, filter; | ||
1408 | |||
1409 | // determine charge pump | ||
1410 | tuner_frequency = params->frequency; | ||
1411 | if (tuner_frequency < 87000000) {return -EINVAL;} | ||
1412 | else if (tuner_frequency < 130000000) {cp = 3; band = 1;} | ||
1413 | else if (tuner_frequency < 160000000) {cp = 5; band = 1;} | ||
1414 | else if (tuner_frequency < 200000000) {cp = 6; band = 1;} | ||
1415 | else if (tuner_frequency < 290000000) {cp = 3; band = 2;} | ||
1416 | else if (tuner_frequency < 420000000) {cp = 5; band = 2;} | ||
1417 | else if (tuner_frequency < 480000000) {cp = 6; band = 2;} | ||
1418 | else if (tuner_frequency < 620000000) {cp = 3; band = 4;} | ||
1419 | else if (tuner_frequency < 830000000) {cp = 5; band = 4;} | ||
1420 | else if (tuner_frequency < 895000000) {cp = 7; band = 4;} | ||
1421 | else {return -EINVAL;} | ||
1422 | |||
1423 | // assume PLL filter should always be 8MHz for the moment. | ||
1424 | filter = 1; | ||
1425 | |||
1426 | // calculate divisor | ||
1427 | // (Finput + Fif)/Fref; Fif = 36125000 Hz, Fref = 62500 Hz | ||
1428 | tuner_frequency = ((params->frequency + 36125000) / 62500); | ||
1429 | |||
1430 | // setup tuner buffer | ||
1431 | tuner_buf[0] = tuner_frequency >> 8; | ||
1432 | tuner_buf[1] = tuner_frequency & 0xff; | ||
1433 | tuner_buf[2] = 0xc8; | ||
1434 | tuner_buf[3] = (cp << 5) | (filter << 3) | band; | ||
1435 | tuner_buf[4] = 0x80; | ||
1436 | |||
1437 | if (fe->ops.i2c_gate_ctrl) | ||
1438 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1439 | if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) { | ||
1440 | printk("dvb-ttusb-budget: dvbc_philips_tdm1316l_pll_set Error 1\n"); | ||
1441 | return -EIO; | ||
1442 | } | ||
1443 | |||
1444 | msleep(50); | ||
1445 | |||
1446 | if (fe->ops.i2c_gate_ctrl) | ||
1447 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
1448 | if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) { | ||
1449 | printk("dvb-ttusb-budget: dvbc_philips_tdm1316l_pll_set Error 2\n"); | ||
1450 | return -EIO; | ||
1451 | } | ||
1452 | |||
1453 | msleep(1); | ||
1454 | |||
1455 | return 0; | ||
1456 | } | ||
1457 | |||
1458 | static u8 dvbc_philips_tdm1316l_inittab[] = { | ||
1459 | 0x80, 0x21, | ||
1460 | 0x80, 0x20, | ||
1461 | 0x81, 0x01, | ||
1462 | 0x81, 0x00, | ||
1463 | 0x00, 0x09, | ||
1464 | 0x01, 0x69, | ||
1465 | 0x03, 0x00, | ||
1466 | 0x04, 0x00, | ||
1467 | 0x07, 0x00, | ||
1468 | 0x08, 0x00, | ||
1469 | 0x20, 0x00, | ||
1470 | 0x21, 0x40, | ||
1471 | 0x22, 0x00, | ||
1472 | 0x23, 0x00, | ||
1473 | 0x24, 0x40, | ||
1474 | 0x25, 0x88, | ||
1475 | 0x30, 0xff, | ||
1476 | 0x31, 0x00, | ||
1477 | 0x32, 0xff, | ||
1478 | 0x33, 0x00, | ||
1479 | 0x34, 0x50, | ||
1480 | 0x35, 0x7f, | ||
1481 | 0x36, 0x00, | ||
1482 | 0x37, 0x20, | ||
1483 | 0x38, 0x00, | ||
1484 | 0x40, 0x1c, | ||
1485 | 0x41, 0xff, | ||
1486 | 0x42, 0x29, | ||
1487 | 0x43, 0x20, | ||
1488 | 0x44, 0xff, | ||
1489 | 0x45, 0x00, | ||
1490 | 0x46, 0x00, | ||
1491 | 0x49, 0x04, | ||
1492 | 0x4a, 0xff, | ||
1493 | 0x4b, 0x7f, | ||
1494 | 0x52, 0x30, | ||
1495 | 0x55, 0xae, | ||
1496 | 0x56, 0x47, | ||
1497 | 0x57, 0xe1, | ||
1498 | 0x58, 0x3a, | ||
1499 | 0x5a, 0x1e, | ||
1500 | 0x5b, 0x34, | ||
1501 | 0x60, 0x00, | ||
1502 | 0x63, 0x00, | ||
1503 | 0x64, 0x00, | ||
1504 | 0x65, 0x00, | ||
1505 | 0x66, 0x00, | ||
1506 | 0x67, 0x00, | ||
1507 | 0x68, 0x00, | ||
1508 | 0x69, 0x00, | ||
1509 | 0x6a, 0x02, | ||
1510 | 0x6b, 0x00, | ||
1511 | 0x70, 0xff, | ||
1512 | 0x71, 0x00, | ||
1513 | 0x72, 0x00, | ||
1514 | 0x73, 0x00, | ||
1515 | 0x74, 0x0c, | ||
1516 | 0x80, 0x00, | ||
1517 | 0x81, 0x00, | ||
1518 | 0x82, 0x00, | ||
1519 | 0x83, 0x00, | ||
1520 | 0x84, 0x04, | ||
1521 | 0x85, 0x80, | ||
1522 | 0x86, 0x24, | ||
1523 | 0x87, 0x78, | ||
1524 | 0x88, 0x00, | ||
1525 | 0x89, 0x00, | ||
1526 | 0x90, 0x01, | ||
1527 | 0x91, 0x01, | ||
1528 | 0xa0, 0x00, | ||
1529 | 0xa1, 0x00, | ||
1530 | 0xa2, 0x00, | ||
1531 | 0xb0, 0x91, | ||
1532 | 0xb1, 0x0b, | ||
1533 | 0xc0, 0x4b, | ||
1534 | 0xc1, 0x00, | ||
1535 | 0xc2, 0x00, | ||
1536 | 0xd0, 0x00, | ||
1537 | 0xd1, 0x00, | ||
1538 | 0xd2, 0x00, | ||
1539 | 0xd3, 0x00, | ||
1540 | 0xd4, 0x00, | ||
1541 | 0xd5, 0x00, | ||
1542 | 0xde, 0x00, | ||
1543 | 0xdf, 0x00, | ||
1544 | 0x61, 0x38, | ||
1545 | 0x62, 0x0a, | ||
1546 | 0x53, 0x13, | ||
1547 | 0x59, 0x08, | ||
1548 | 0x55, 0x00, | ||
1549 | 0x56, 0x40, | ||
1550 | 0x57, 0x08, | ||
1551 | 0x58, 0x3d, | ||
1552 | 0x88, 0x10, | ||
1553 | 0xa0, 0x00, | ||
1554 | 0xa0, 0x00, | ||
1555 | 0xa0, 0x00, | ||
1556 | 0xa0, 0x04, | ||
1557 | 0xff, 0xff, | ||
1558 | }; | ||
1559 | |||
1560 | static struct stv0297_config dvbc_philips_tdm1316l_config = { | ||
1561 | .demod_address = 0x1c, | ||
1562 | .inittab = dvbc_philips_tdm1316l_inittab, | ||
1563 | .invert = 0, | ||
1564 | }; | ||
1565 | |||
1413 | static void frontend_init(struct ttusb* ttusb) | 1566 | static void frontend_init(struct ttusb* ttusb) |
1414 | { | 1567 | { |
1415 | switch(le16_to_cpu(ttusb->dev->descriptor.idProduct)) { | 1568 | switch(le16_to_cpu(ttusb->dev->descriptor.idProduct)) { |
@@ -1417,11 +1570,13 @@ static void frontend_init(struct ttusb* ttusb) | |||
1417 | // try the stv0299 based first | 1570 | // try the stv0299 based first |
1418 | ttusb->fe = stv0299_attach(&alps_stv0299_config, &ttusb->i2c_adap); | 1571 | ttusb->fe = stv0299_attach(&alps_stv0299_config, &ttusb->i2c_adap); |
1419 | if (ttusb->fe != NULL) { | 1572 | if (ttusb->fe != NULL) { |
1573 | ttusb->fe->ops.tuner_ops.set_params = philips_tsa5059_tuner_set_params; | ||
1574 | |||
1420 | if(ttusb->revision == TTUSB_REV_2_2) { // ALPS BSBE1 | 1575 | if(ttusb->revision == TTUSB_REV_2_2) { // ALPS BSBE1 |
1421 | alps_stv0299_config.inittab = alps_bsbe1_inittab; | 1576 | alps_stv0299_config.inittab = alps_bsbe1_inittab; |
1422 | ttusb->fe->ops->set_voltage = lnbp21_set_voltage; | 1577 | lnbp21_attach(ttusb->fe, &ttusb->i2c_adap, 0, 0); |
1423 | } else { // ALPS BSRU6 | 1578 | } else { // ALPS BSRU6 |
1424 | ttusb->fe->ops->set_voltage = ttusb_set_voltage; | 1579 | ttusb->fe->ops.set_voltage = ttusb_set_voltage; |
1425 | } | 1580 | } |
1426 | break; | 1581 | break; |
1427 | } | 1582 | } |
@@ -1429,28 +1584,41 @@ static void frontend_init(struct ttusb* ttusb) | |||
1429 | // Grundig 29504-491 | 1584 | // Grundig 29504-491 |
1430 | ttusb->fe = tda8083_attach(&ttusb_novas_grundig_29504_491_config, &ttusb->i2c_adap); | 1585 | ttusb->fe = tda8083_attach(&ttusb_novas_grundig_29504_491_config, &ttusb->i2c_adap); |
1431 | if (ttusb->fe != NULL) { | 1586 | if (ttusb->fe != NULL) { |
1432 | ttusb->fe->ops->set_voltage = ttusb_set_voltage; | 1587 | ttusb->fe->ops.tuner_ops.set_params = ttusb_novas_grundig_29504_491_tuner_set_params; |
1588 | ttusb->fe->ops.set_voltage = ttusb_set_voltage; | ||
1433 | break; | 1589 | break; |
1434 | } | 1590 | } |
1435 | |||
1436 | break; | 1591 | break; |
1437 | 1592 | ||
1438 | case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659)) | 1593 | case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659)) |
1439 | ttusb->fe = ves1820_attach(&alps_tdbe2_config, &ttusb->i2c_adap, read_pwm(ttusb)); | 1594 | ttusb->fe = ves1820_attach(&alps_tdbe2_config, &ttusb->i2c_adap, read_pwm(ttusb)); |
1440 | if (ttusb->fe != NULL) | 1595 | if (ttusb->fe != NULL) { |
1596 | ttusb->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params; | ||
1597 | break; | ||
1598 | } | ||
1599 | |||
1600 | ttusb->fe = stv0297_attach(&dvbc_philips_tdm1316l_config, &ttusb->i2c_adap); | ||
1601 | if (ttusb->fe != NULL) { | ||
1602 | ttusb->fe->ops.tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params; | ||
1441 | break; | 1603 | break; |
1604 | } | ||
1442 | break; | 1605 | break; |
1443 | 1606 | ||
1444 | case 0x1005: // Hauppauge/TT Nova-USB-t budget (tda10046/Philips td1316(tda6651tt) OR cx22700/ALPS TDMB7(??)) | 1607 | case 0x1005: // Hauppauge/TT Nova-USB-t budget (tda10046/Philips td1316(tda6651tt) OR cx22700/ALPS TDMB7(??)) |
1445 | // try the ALPS TDMB7 first | 1608 | // try the ALPS TDMB7 first |
1446 | ttusb->fe = cx22700_attach(&alps_tdmb7_config, &ttusb->i2c_adap); | 1609 | ttusb->fe = cx22700_attach(&alps_tdmb7_config, &ttusb->i2c_adap); |
1447 | if (ttusb->fe != NULL) | 1610 | if (ttusb->fe != NULL) { |
1611 | ttusb->fe->ops.tuner_ops.set_params = alps_tdmb7_tuner_set_params; | ||
1448 | break; | 1612 | break; |
1613 | } | ||
1449 | 1614 | ||
1450 | // Philips td1316 | 1615 | // Philips td1316 |
1451 | ttusb->fe = tda10046_attach(&philips_tdm1316l_config, &ttusb->i2c_adap); | 1616 | ttusb->fe = tda10046_attach(&philips_tdm1316l_config, &ttusb->i2c_adap); |
1452 | if (ttusb->fe != NULL) | 1617 | if (ttusb->fe != NULL) { |
1618 | ttusb->fe->ops.tuner_ops.init = philips_tdm1316l_tuner_init; | ||
1619 | ttusb->fe->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params; | ||
1453 | break; | 1620 | break; |
1621 | } | ||
1454 | break; | 1622 | break; |
1455 | } | 1623 | } |
1456 | 1624 | ||
@@ -1461,8 +1629,8 @@ static void frontend_init(struct ttusb* ttusb) | |||
1461 | } else { | 1629 | } else { |
1462 | if (dvb_register_frontend(&ttusb->adapter, ttusb->fe)) { | 1630 | if (dvb_register_frontend(&ttusb->adapter, ttusb->fe)) { |
1463 | printk("dvb-ttusb-budget: Frontend registration failed!\n"); | 1631 | printk("dvb-ttusb-budget: Frontend registration failed!\n"); |
1464 | if (ttusb->fe->ops->release) | 1632 | if (ttusb->fe->ops.release) |
1465 | ttusb->fe->ops->release(ttusb->fe); | 1633 | ttusb->fe->ops.release(ttusb->fe); |
1466 | ttusb->fe = NULL; | 1634 | ttusb->fe = NULL; |
1467 | } | 1635 | } |
1468 | } | 1636 | } |
@@ -1507,7 +1675,7 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
1507 | 1675 | ||
1508 | mutex_unlock(&ttusb->semi2c); | 1676 | mutex_unlock(&ttusb->semi2c); |
1509 | 1677 | ||
1510 | if ((result = dvb_register_adapter(&ttusb->adapter, "Technotrend/Hauppauge Nova-USB", THIS_MODULE)) < 0) { | 1678 | if ((result = dvb_register_adapter(&ttusb->adapter, "Technotrend/Hauppauge Nova-USB", THIS_MODULE, &udev->dev)) < 0) { |
1511 | ttusb_free_iso_urbs(ttusb); | 1679 | ttusb_free_iso_urbs(ttusb); |
1512 | kfree(ttusb); | 1680 | kfree(ttusb); |
1513 | return result; | 1681 | return result; |
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c index 44dea3211848..6c1cb770bcf5 100644 --- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c +++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c | |||
@@ -1432,7 +1432,7 @@ static int ttusb_dec_init_dvb(struct ttusb_dec *dec) | |||
1432 | dprintk("%s\n", __FUNCTION__); | 1432 | dprintk("%s\n", __FUNCTION__); |
1433 | 1433 | ||
1434 | if ((result = dvb_register_adapter(&dec->adapter, | 1434 | if ((result = dvb_register_adapter(&dec->adapter, |
1435 | dec->model_name, THIS_MODULE)) < 0) { | 1435 | dec->model_name, THIS_MODULE, &dec->udev->dev)) < 0) { |
1436 | printk("%s: dvb_register_adapter failed: error %d\n", | 1436 | printk("%s: dvb_register_adapter failed: error %d\n", |
1437 | __FUNCTION__, result); | 1437 | __FUNCTION__, result); |
1438 | 1438 | ||
@@ -1657,8 +1657,8 @@ static int ttusb_dec_probe(struct usb_interface *intf, | |||
1657 | } else { | 1657 | } else { |
1658 | if (dvb_register_frontend(&dec->adapter, dec->fe)) { | 1658 | if (dvb_register_frontend(&dec->adapter, dec->fe)) { |
1659 | printk("budget-ci: Frontend registration failed!\n"); | 1659 | printk("budget-ci: Frontend registration failed!\n"); |
1660 | if (dec->fe->ops->release) | 1660 | if (dec->fe->ops.release) |
1661 | dec->fe->ops->release(dec->fe); | 1661 | dec->fe->ops.release(dec->fe); |
1662 | dec->fe = NULL; | 1662 | dec->fe = NULL; |
1663 | } | 1663 | } |
1664 | } | 1664 | } |
diff --git a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c index a5a46175fa09..42f39a89bc4d 100644 --- a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c +++ b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c | |||
@@ -28,8 +28,6 @@ | |||
28 | 28 | ||
29 | struct ttusbdecfe_state { | 29 | struct ttusbdecfe_state { |
30 | 30 | ||
31 | struct dvb_frontend_ops ops; | ||
32 | |||
33 | /* configuration settings */ | 31 | /* configuration settings */ |
34 | const struct ttusbdecfe_config* config; | 32 | const struct ttusbdecfe_config* config; |
35 | 33 | ||
@@ -203,10 +201,9 @@ struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* conf | |||
203 | 201 | ||
204 | /* setup the state */ | 202 | /* setup the state */ |
205 | state->config = config; | 203 | state->config = config; |
206 | memcpy(&state->ops, &ttusbdecfe_dvbt_ops, sizeof(struct dvb_frontend_ops)); | ||
207 | 204 | ||
208 | /* create dvb_frontend */ | 205 | /* create dvb_frontend */ |
209 | state->frontend.ops = &state->ops; | 206 | memcpy(&state->frontend.ops, &ttusbdecfe_dvbt_ops, sizeof(struct dvb_frontend_ops)); |
210 | state->frontend.demodulator_priv = state; | 207 | state->frontend.demodulator_priv = state; |
211 | return &state->frontend; | 208 | return &state->frontend; |
212 | } | 209 | } |
@@ -226,10 +223,9 @@ struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* conf | |||
226 | state->config = config; | 223 | state->config = config; |
227 | state->voltage = 0; | 224 | state->voltage = 0; |
228 | state->hi_band = 0; | 225 | state->hi_band = 0; |
229 | memcpy(&state->ops, &ttusbdecfe_dvbs_ops, sizeof(struct dvb_frontend_ops)); | ||
230 | 226 | ||
231 | /* create dvb_frontend */ | 227 | /* create dvb_frontend */ |
232 | state->frontend.ops = &state->ops; | 228 | memcpy(&state->frontend.ops, &ttusbdecfe_dvbs_ops, sizeof(struct dvb_frontend_ops)); |
233 | state->frontend.demodulator_priv = state; | 229 | state->frontend.demodulator_priv = state; |
234 | return &state->frontend; | 230 | return &state->frontend; |
235 | } | 231 | } |