diff options
author | David S. Miller <davem@davemloft.net> | 2010-02-28 22:23:06 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-02-28 22:23:06 -0500 |
commit | 47871889c601d8199c51a4086f77eebd77c29b0b (patch) | |
tree | 40cdcac3bff0ee40cc33dcca61d0577cdf965f77 /drivers/media/dvb | |
parent | c16cc0b464b8876cfd57ce1c1dbcb6f9a6a0bce3 (diff) | |
parent | 30ff056c42c665b9ea535d8515890857ae382540 (diff) |
Merge branch 'master' of /home/davem/src/GIT/linux-2.6/
Conflicts:
drivers/firmware/iscsi_ibft.c
Diffstat (limited to 'drivers/media/dvb')
70 files changed, 6399 insertions, 1154 deletions
diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig index cf8f65f309da..161ccfd471cb 100644 --- a/drivers/media/dvb/Kconfig +++ b/drivers/media/dvb/Kconfig | |||
@@ -76,6 +76,10 @@ comment "Supported Mantis Adapters" | |||
76 | depends on DVB_CORE && PCI && I2C | 76 | depends on DVB_CORE && PCI && I2C |
77 | source "drivers/media/dvb/mantis/Kconfig" | 77 | source "drivers/media/dvb/mantis/Kconfig" |
78 | 78 | ||
79 | comment "Supported nGene Adapters" | ||
80 | depends on DVB_CORE && PCI && I2C | ||
81 | source "drivers/media/dvb/ngene/Kconfig" | ||
82 | |||
79 | comment "Supported DVB Frontends" | 83 | comment "Supported DVB Frontends" |
80 | depends on DVB_CORE | 84 | depends on DVB_CORE |
81 | source "drivers/media/dvb/frontends/Kconfig" | 85 | source "drivers/media/dvb/frontends/Kconfig" |
diff --git a/drivers/media/dvb/Makefile b/drivers/media/dvb/Makefile index c12922c3659b..a1a08758a6f2 100644 --- a/drivers/media/dvb/Makefile +++ b/drivers/media/dvb/Makefile | |||
@@ -14,6 +14,7 @@ obj-y := dvb-core/ \ | |||
14 | siano/ \ | 14 | siano/ \ |
15 | dm1105/ \ | 15 | dm1105/ \ |
16 | pt1/ \ | 16 | pt1/ \ |
17 | mantis/ | 17 | mantis/ \ |
18 | ngene/ | ||
18 | 19 | ||
19 | obj-$(CONFIG_DVB_FIREDTV) += firewire/ | 20 | obj-$(CONFIG_DVB_FIREDTV) += firewire/ |
diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/dvb/bt8xx/bt878.c index a24c125331f0..99d62094f908 100644 --- a/drivers/media/dvb/bt8xx/bt878.c +++ b/drivers/media/dvb/bt8xx/bt878.c | |||
@@ -576,43 +576,30 @@ static struct pci_driver bt878_pci_driver = { | |||
576 | .remove = __devexit_p(bt878_remove), | 576 | .remove = __devexit_p(bt878_remove), |
577 | }; | 577 | }; |
578 | 578 | ||
579 | static int bt878_pci_driver_registered; | ||
580 | |||
581 | /*******************************/ | 579 | /*******************************/ |
582 | /* Module management functions */ | 580 | /* Module management functions */ |
583 | /*******************************/ | 581 | /*******************************/ |
584 | 582 | ||
585 | static int bt878_init_module(void) | 583 | static int __init bt878_init_module(void) |
586 | { | 584 | { |
587 | bt878_num = 0; | 585 | bt878_num = 0; |
588 | bt878_pci_driver_registered = 0; | ||
589 | 586 | ||
590 | printk(KERN_INFO "bt878: AUDIO driver version %d.%d.%d loaded\n", | 587 | printk(KERN_INFO "bt878: AUDIO driver version %d.%d.%d loaded\n", |
591 | (BT878_VERSION_CODE >> 16) & 0xff, | 588 | (BT878_VERSION_CODE >> 16) & 0xff, |
592 | (BT878_VERSION_CODE >> 8) & 0xff, | 589 | (BT878_VERSION_CODE >> 8) & 0xff, |
593 | BT878_VERSION_CODE & 0xff); | 590 | BT878_VERSION_CODE & 0xff); |
594 | /* | 591 | |
595 | bt878_check_chipset(); | ||
596 | */ | ||
597 | /* later we register inside of bt878_find_audio_dma() | ||
598 | * because we may want to ignore certain cards */ | ||
599 | bt878_pci_driver_registered = 1; | ||
600 | return pci_register_driver(&bt878_pci_driver); | 592 | return pci_register_driver(&bt878_pci_driver); |
601 | } | 593 | } |
602 | 594 | ||
603 | static void bt878_cleanup_module(void) | 595 | static void __exit bt878_cleanup_module(void) |
604 | { | 596 | { |
605 | if (bt878_pci_driver_registered) { | 597 | pci_unregister_driver(&bt878_pci_driver); |
606 | bt878_pci_driver_registered = 0; | ||
607 | pci_unregister_driver(&bt878_pci_driver); | ||
608 | } | ||
609 | return; | ||
610 | } | 598 | } |
611 | 599 | ||
612 | module_init(bt878_init_module); | 600 | module_init(bt878_init_module); |
613 | module_exit(bt878_cleanup_module); | 601 | module_exit(bt878_cleanup_module); |
614 | 602 | ||
615 | //MODULE_AUTHOR("XXX"); | ||
616 | MODULE_LICENSE("GPL"); | 603 | MODULE_LICENSE("GPL"); |
617 | 604 | ||
618 | /* | 605 | /* |
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c index 91353a6faf1d..8b0cde38984d 100644 --- a/drivers/media/dvb/bt8xx/dst.c +++ b/drivers/media/dvb/bt8xx/dst.c | |||
@@ -1352,8 +1352,7 @@ static int dst_get_tuna(struct dst_state *state) | |||
1352 | return retval; | 1352 | return retval; |
1353 | } | 1353 | } |
1354 | if ((state->type_flags & DST_TYPE_HAS_VLF) && | 1354 | if ((state->type_flags & DST_TYPE_HAS_VLF) && |
1355 | !(state->dst_type == DST_TYPE_IS_CABLE) && | 1355 | !(state->dst_type == DST_TYPE_IS_ATSC)) { |
1356 | !(state->dst_type == DST_TYPE_IS_ATSC)) { | ||
1357 | 1356 | ||
1358 | if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) { | 1357 | if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) { |
1359 | dprintk(verbose, DST_INFO, 1, "checksum failure ? "); | 1358 | dprintk(verbose, DST_INFO, 1, "checksum failure ? "); |
@@ -1820,8 +1819,13 @@ static struct dvb_frontend_ops dst_dvbc_ops = { | |||
1820 | .frequency_max = 858000000, | 1819 | .frequency_max = 858000000, |
1821 | .symbol_rate_min = 1000000, | 1820 | .symbol_rate_min = 1000000, |
1822 | .symbol_rate_max = 45000000, | 1821 | .symbol_rate_max = 45000000, |
1823 | /* . symbol_rate_tolerance = ???,*/ | 1822 | .caps = FE_CAN_FEC_AUTO | |
1824 | .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO | 1823 | FE_CAN_QAM_AUTO | |
1824 | FE_CAN_QAM_16 | | ||
1825 | FE_CAN_QAM_32 | | ||
1826 | FE_CAN_QAM_64 | | ||
1827 | FE_CAN_QAM_128 | | ||
1828 | FE_CAN_QAM_256 | ||
1825 | }, | 1829 | }, |
1826 | 1830 | ||
1827 | .release = dst_release, | 1831 | .release = dst_release, |
diff --git a/drivers/media/dvb/dm1105/Kconfig b/drivers/media/dvb/dm1105/Kconfig index de3eeb0a8d6e..695239227cb7 100644 --- a/drivers/media/dvb/dm1105/Kconfig +++ b/drivers/media/dvb/dm1105/Kconfig | |||
@@ -8,6 +8,7 @@ config DVB_DM1105 | |||
8 | select DVB_STB6000 if !DVB_FE_CUSTOMISE | 8 | select DVB_STB6000 if !DVB_FE_CUSTOMISE |
9 | select DVB_CX24116 if !DVB_FE_CUSTOMISE | 9 | select DVB_CX24116 if !DVB_FE_CUSTOMISE |
10 | select DVB_SI21XX if !DVB_FE_CUSTOMISE | 10 | select DVB_SI21XX if !DVB_FE_CUSTOMISE |
11 | select DVB_DS3000 if !DVB_FE_CUSTOMISE | ||
11 | select VIDEO_IR | 12 | select VIDEO_IR |
12 | help | 13 | help |
13 | Support for cards based on the SDMC DM1105 PCI chip like | 14 | Support for cards based on the SDMC DM1105 PCI chip like |
diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c index f0f483ac8b89..383cca378b8c 100644 --- a/drivers/media/dvb/dm1105/dm1105.c +++ b/drivers/media/dvb/dm1105/dm1105.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include "si21xx.h" | 43 | #include "si21xx.h" |
44 | #include "cx24116.h" | 44 | #include "cx24116.h" |
45 | #include "z0194a.h" | 45 | #include "z0194a.h" |
46 | #include "ds3000.h" | ||
46 | 47 | ||
47 | #define UNSET (-1U) | 48 | #define UNSET (-1U) |
48 | 49 | ||
@@ -269,7 +270,7 @@ struct infrared { | |||
269 | u32 ir_command; | 270 | u32 ir_command; |
270 | }; | 271 | }; |
271 | 272 | ||
272 | struct dm1105dvb { | 273 | struct dm1105_dev { |
273 | /* pci */ | 274 | /* pci */ |
274 | struct pci_dev *pdev; | 275 | struct pci_dev *pdev; |
275 | u8 __iomem *io_mem; | 276 | u8 __iomem *io_mem; |
@@ -308,31 +309,47 @@ struct dm1105dvb { | |||
308 | spinlock_t lock; | 309 | spinlock_t lock; |
309 | }; | 310 | }; |
310 | 311 | ||
311 | #define dm_io_mem(reg) ((unsigned long)(&dm1105dvb->io_mem[reg])) | 312 | #define dm_io_mem(reg) ((unsigned long)(&dev->io_mem[reg])) |
313 | |||
314 | #define dm_readb(reg) inb(dm_io_mem(reg)) | ||
315 | #define dm_writeb(reg, value) outb((value), (dm_io_mem(reg))) | ||
316 | |||
317 | #define dm_readw(reg) inw(dm_io_mem(reg)) | ||
318 | #define dm_writew(reg, value) outw((value), (dm_io_mem(reg))) | ||
319 | |||
320 | #define dm_readl(reg) inl(dm_io_mem(reg)) | ||
321 | #define dm_writel(reg, value) outl((value), (dm_io_mem(reg))) | ||
322 | |||
323 | #define dm_andorl(reg, mask, value) \ | ||
324 | outl((inl(dm_io_mem(reg)) & ~(mask)) |\ | ||
325 | ((value) & (mask)), (dm_io_mem(reg))) | ||
326 | |||
327 | #define dm_setl(reg, bit) dm_andorl((reg), (bit), (bit)) | ||
328 | #define dm_clearl(reg, bit) dm_andorl((reg), (bit), 0) | ||
312 | 329 | ||
313 | static int dm1105_i2c_xfer(struct i2c_adapter *i2c_adap, | 330 | static int dm1105_i2c_xfer(struct i2c_adapter *i2c_adap, |
314 | struct i2c_msg *msgs, int num) | 331 | struct i2c_msg *msgs, int num) |
315 | { | 332 | { |
316 | struct dm1105dvb *dm1105dvb ; | 333 | struct dm1105_dev *dev ; |
317 | 334 | ||
318 | int addr, rc, i, j, k, len, byte, data; | 335 | int addr, rc, i, j, k, len, byte, data; |
319 | u8 status; | 336 | u8 status; |
320 | 337 | ||
321 | dm1105dvb = i2c_adap->algo_data; | 338 | dev = i2c_adap->algo_data; |
322 | for (i = 0; i < num; i++) { | 339 | for (i = 0; i < num; i++) { |
323 | outb(0x00, dm_io_mem(DM1105_I2CCTR)); | 340 | dm_writeb(DM1105_I2CCTR, 0x00); |
324 | if (msgs[i].flags & I2C_M_RD) { | 341 | if (msgs[i].flags & I2C_M_RD) { |
325 | /* read bytes */ | 342 | /* read bytes */ |
326 | addr = msgs[i].addr << 1; | 343 | addr = msgs[i].addr << 1; |
327 | addr |= 1; | 344 | addr |= 1; |
328 | outb(addr, dm_io_mem(DM1105_I2CDAT)); | 345 | dm_writeb(DM1105_I2CDAT, addr); |
329 | for (byte = 0; byte < msgs[i].len; byte++) | 346 | for (byte = 0; byte < msgs[i].len; byte++) |
330 | outb(0, dm_io_mem(DM1105_I2CDAT + byte + 1)); | 347 | dm_writeb(DM1105_I2CDAT + byte + 1, 0); |
331 | 348 | ||
332 | outb(0x81 + msgs[i].len, dm_io_mem(DM1105_I2CCTR)); | 349 | dm_writeb(DM1105_I2CCTR, 0x81 + msgs[i].len); |
333 | for (j = 0; j < 55; j++) { | 350 | for (j = 0; j < 55; j++) { |
334 | mdelay(10); | 351 | mdelay(10); |
335 | status = inb(dm_io_mem(DM1105_I2CSTS)); | 352 | status = dm_readb(DM1105_I2CSTS); |
336 | if ((status & 0xc0) == 0x40) | 353 | if ((status & 0xc0) == 0x40) |
337 | break; | 354 | break; |
338 | } | 355 | } |
@@ -340,56 +357,54 @@ static int dm1105_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
340 | return -1; | 357 | return -1; |
341 | 358 | ||
342 | for (byte = 0; byte < msgs[i].len; byte++) { | 359 | for (byte = 0; byte < msgs[i].len; byte++) { |
343 | rc = inb(dm_io_mem(DM1105_I2CDAT + byte + 1)); | 360 | rc = dm_readb(DM1105_I2CDAT + byte + 1); |
344 | if (rc < 0) | 361 | if (rc < 0) |
345 | goto err; | 362 | goto err; |
346 | msgs[i].buf[byte] = rc; | 363 | msgs[i].buf[byte] = rc; |
347 | } | 364 | } |
348 | } else { | 365 | } else if ((msgs[i].buf[0] == 0xf7) && (msgs[i].addr == 0x55)) { |
349 | if ((msgs[i].buf[0] == 0xf7) && (msgs[i].addr == 0x55)) { | 366 | /* prepaired for cx24116 firmware */ |
350 | /* prepaired for cx24116 firmware */ | 367 | /* Write in small blocks */ |
351 | /* Write in small blocks */ | 368 | len = msgs[i].len - 1; |
352 | len = msgs[i].len - 1; | 369 | k = 1; |
353 | k = 1; | 370 | do { |
354 | do { | 371 | dm_writeb(DM1105_I2CDAT, msgs[i].addr << 1); |
355 | outb(msgs[i].addr << 1, dm_io_mem(DM1105_I2CDAT)); | 372 | dm_writeb(DM1105_I2CDAT + 1, 0xf7); |
356 | outb(0xf7, dm_io_mem(DM1105_I2CDAT + 1)); | 373 | for (byte = 0; byte < (len > 48 ? 48 : len); byte++) { |
357 | for (byte = 0; byte < (len > 48 ? 48 : len); byte++) { | 374 | data = msgs[i].buf[k + byte]; |
358 | data = msgs[i].buf[k+byte]; | 375 | dm_writeb(DM1105_I2CDAT + byte + 2, data); |
359 | outb(data, dm_io_mem(DM1105_I2CDAT + byte + 2)); | ||
360 | } | ||
361 | outb(0x82 + (len > 48 ? 48 : len), dm_io_mem(DM1105_I2CCTR)); | ||
362 | for (j = 0; j < 25; j++) { | ||
363 | mdelay(10); | ||
364 | status = inb(dm_io_mem(DM1105_I2CSTS)); | ||
365 | if ((status & 0xc0) == 0x40) | ||
366 | break; | ||
367 | } | ||
368 | |||
369 | if (j >= 25) | ||
370 | return -1; | ||
371 | |||
372 | k += 48; | ||
373 | len -= 48; | ||
374 | } while (len > 0); | ||
375 | } else { | ||
376 | /* write bytes */ | ||
377 | outb(msgs[i].addr<<1, dm_io_mem(DM1105_I2CDAT)); | ||
378 | for (byte = 0; byte < msgs[i].len; byte++) { | ||
379 | data = msgs[i].buf[byte]; | ||
380 | outb(data, dm_io_mem(DM1105_I2CDAT + byte + 1)); | ||
381 | } | 376 | } |
382 | outb(0x81 + msgs[i].len, dm_io_mem(DM1105_I2CCTR)); | 377 | dm_writeb(DM1105_I2CCTR, 0x82 + (len > 48 ? 48 : len)); |
383 | for (j = 0; j < 25; j++) { | 378 | for (j = 0; j < 25; j++) { |
384 | mdelay(10); | 379 | mdelay(10); |
385 | status = inb(dm_io_mem(DM1105_I2CSTS)); | 380 | status = dm_readb(DM1105_I2CSTS); |
386 | if ((status & 0xc0) == 0x40) | 381 | if ((status & 0xc0) == 0x40) |
387 | break; | 382 | break; |
388 | } | 383 | } |
389 | 384 | ||
390 | if (j >= 25) | 385 | if (j >= 25) |
391 | return -1; | 386 | return -1; |
387 | |||
388 | k += 48; | ||
389 | len -= 48; | ||
390 | } while (len > 0); | ||
391 | } else { | ||
392 | /* write bytes */ | ||
393 | dm_writeb(DM1105_I2CDAT, msgs[i].addr << 1); | ||
394 | for (byte = 0; byte < msgs[i].len; byte++) { | ||
395 | data = msgs[i].buf[byte]; | ||
396 | dm_writeb(DM1105_I2CDAT + byte + 1, data); | ||
392 | } | 397 | } |
398 | dm_writeb(DM1105_I2CCTR, 0x81 + msgs[i].len); | ||
399 | for (j = 0; j < 25; j++) { | ||
400 | mdelay(10); | ||
401 | status = dm_readb(DM1105_I2CSTS); | ||
402 | if ((status & 0xc0) == 0x40) | ||
403 | break; | ||
404 | } | ||
405 | |||
406 | if (j >= 25) | ||
407 | return -1; | ||
393 | } | 408 | } |
394 | } | 409 | } |
395 | return num; | 410 | return num; |
@@ -407,22 +422,22 @@ static struct i2c_algorithm dm1105_algo = { | |||
407 | .functionality = functionality, | 422 | .functionality = functionality, |
408 | }; | 423 | }; |
409 | 424 | ||
410 | static inline struct dm1105dvb *feed_to_dm1105dvb(struct dvb_demux_feed *feed) | 425 | static inline struct dm1105_dev *feed_to_dm1105_dev(struct dvb_demux_feed *feed) |
411 | { | 426 | { |
412 | return container_of(feed->demux, struct dm1105dvb, demux); | 427 | return container_of(feed->demux, struct dm1105_dev, demux); |
413 | } | 428 | } |
414 | 429 | ||
415 | static inline struct dm1105dvb *frontend_to_dm1105dvb(struct dvb_frontend *fe) | 430 | static inline struct dm1105_dev *frontend_to_dm1105_dev(struct dvb_frontend *fe) |
416 | { | 431 | { |
417 | return container_of(fe->dvb, struct dm1105dvb, dvb_adapter); | 432 | return container_of(fe->dvb, struct dm1105_dev, dvb_adapter); |
418 | } | 433 | } |
419 | 434 | ||
420 | static int dm1105dvb_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | 435 | static int dm1105_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) |
421 | { | 436 | { |
422 | struct dm1105dvb *dm1105dvb = frontend_to_dm1105dvb(fe); | 437 | struct dm1105_dev *dev = frontend_to_dm1105_dev(fe); |
423 | u32 lnb_mask, lnb_13v, lnb_18v, lnb_off; | 438 | u32 lnb_mask, lnb_13v, lnb_18v, lnb_off; |
424 | 439 | ||
425 | switch (dm1105dvb->boardnr) { | 440 | switch (dev->boardnr) { |
426 | case DM1105_BOARD_AXESS_DM05: | 441 | case DM1105_BOARD_AXESS_DM05: |
427 | lnb_mask = DM05_LNB_MASK; | 442 | lnb_mask = DM05_LNB_MASK; |
428 | lnb_off = DM05_LNB_OFF; | 443 | lnb_off = DM05_LNB_OFF; |
@@ -438,62 +453,67 @@ static int dm1105dvb_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volta | |||
438 | lnb_18v = DM1105_LNB_18V; | 453 | lnb_18v = DM1105_LNB_18V; |
439 | } | 454 | } |
440 | 455 | ||
441 | outl(lnb_mask, dm_io_mem(DM1105_GPIOCTR)); | 456 | dm_writel(DM1105_GPIOCTR, lnb_mask); |
442 | if (voltage == SEC_VOLTAGE_18) | 457 | if (voltage == SEC_VOLTAGE_18) |
443 | outl(lnb_18v , dm_io_mem(DM1105_GPIOVAL)); | 458 | dm_writel(DM1105_GPIOVAL, lnb_18v); |
444 | else if (voltage == SEC_VOLTAGE_13) | 459 | else if (voltage == SEC_VOLTAGE_13) |
445 | outl(lnb_13v, dm_io_mem(DM1105_GPIOVAL)); | 460 | dm_writel(DM1105_GPIOVAL, lnb_13v); |
446 | else | 461 | else |
447 | outl(lnb_off, dm_io_mem(DM1105_GPIOVAL)); | 462 | dm_writel(DM1105_GPIOVAL, lnb_off); |
448 | 463 | ||
449 | return 0; | 464 | return 0; |
450 | } | 465 | } |
451 | 466 | ||
452 | static void dm1105dvb_set_dma_addr(struct dm1105dvb *dm1105dvb) | 467 | static void dm1105_set_dma_addr(struct dm1105_dev *dev) |
453 | { | 468 | { |
454 | outl(cpu_to_le32(dm1105dvb->dma_addr), dm_io_mem(DM1105_STADR)); | 469 | dm_writel(DM1105_STADR, cpu_to_le32(dev->dma_addr)); |
455 | } | 470 | } |
456 | 471 | ||
457 | static int __devinit dm1105dvb_dma_map(struct dm1105dvb *dm1105dvb) | 472 | static int __devinit dm1105_dma_map(struct dm1105_dev *dev) |
458 | { | 473 | { |
459 | dm1105dvb->ts_buf = pci_alloc_consistent(dm1105dvb->pdev, 6*DM1105_DMA_BYTES, &dm1105dvb->dma_addr); | 474 | dev->ts_buf = pci_alloc_consistent(dev->pdev, |
475 | 6 * DM1105_DMA_BYTES, | ||
476 | &dev->dma_addr); | ||
460 | 477 | ||
461 | return !dm1105dvb->ts_buf; | 478 | return !dev->ts_buf; |
462 | } | 479 | } |
463 | 480 | ||
464 | static void dm1105dvb_dma_unmap(struct dm1105dvb *dm1105dvb) | 481 | static void dm1105_dma_unmap(struct dm1105_dev *dev) |
465 | { | 482 | { |
466 | pci_free_consistent(dm1105dvb->pdev, 6*DM1105_DMA_BYTES, dm1105dvb->ts_buf, dm1105dvb->dma_addr); | 483 | pci_free_consistent(dev->pdev, |
484 | 6 * DM1105_DMA_BYTES, | ||
485 | dev->ts_buf, | ||
486 | dev->dma_addr); | ||
467 | } | 487 | } |
468 | 488 | ||
469 | static void dm1105dvb_enable_irqs(struct dm1105dvb *dm1105dvb) | 489 | static void dm1105_enable_irqs(struct dm1105_dev *dev) |
470 | { | 490 | { |
471 | outb(INTMAK_ALLMASK, dm_io_mem(DM1105_INTMAK)); | 491 | dm_writeb(DM1105_INTMAK, INTMAK_ALLMASK); |
472 | outb(1, dm_io_mem(DM1105_CR)); | 492 | dm_writeb(DM1105_CR, 1); |
473 | } | 493 | } |
474 | 494 | ||
475 | static void dm1105dvb_disable_irqs(struct dm1105dvb *dm1105dvb) | 495 | static void dm1105_disable_irqs(struct dm1105_dev *dev) |
476 | { | 496 | { |
477 | outb(INTMAK_IRM, dm_io_mem(DM1105_INTMAK)); | 497 | dm_writeb(DM1105_INTMAK, INTMAK_IRM); |
478 | outb(0, dm_io_mem(DM1105_CR)); | 498 | dm_writeb(DM1105_CR, 0); |
479 | } | 499 | } |
480 | 500 | ||
481 | static int dm1105dvb_start_feed(struct dvb_demux_feed *f) | 501 | static int dm1105_start_feed(struct dvb_demux_feed *f) |
482 | { | 502 | { |
483 | struct dm1105dvb *dm1105dvb = feed_to_dm1105dvb(f); | 503 | struct dm1105_dev *dev = feed_to_dm1105_dev(f); |
484 | 504 | ||
485 | if (dm1105dvb->full_ts_users++ == 0) | 505 | if (dev->full_ts_users++ == 0) |
486 | dm1105dvb_enable_irqs(dm1105dvb); | 506 | dm1105_enable_irqs(dev); |
487 | 507 | ||
488 | return 0; | 508 | return 0; |
489 | } | 509 | } |
490 | 510 | ||
491 | static int dm1105dvb_stop_feed(struct dvb_demux_feed *f) | 511 | static int dm1105_stop_feed(struct dvb_demux_feed *f) |
492 | { | 512 | { |
493 | struct dm1105dvb *dm1105dvb = feed_to_dm1105dvb(f); | 513 | struct dm1105_dev *dev = feed_to_dm1105_dev(f); |
494 | 514 | ||
495 | if (--dm1105dvb->full_ts_users == 0) | 515 | if (--dev->full_ts_users == 0) |
496 | dm1105dvb_disable_irqs(dm1105dvb); | 516 | dm1105_disable_irqs(dev); |
497 | 517 | ||
498 | return 0; | 518 | return 0; |
499 | } | 519 | } |
@@ -517,68 +537,64 @@ static void dm1105_emit_key(struct work_struct *work) | |||
517 | /* work handler */ | 537 | /* work handler */ |
518 | static void dm1105_dmx_buffer(struct work_struct *work) | 538 | static void dm1105_dmx_buffer(struct work_struct *work) |
519 | { | 539 | { |
520 | struct dm1105dvb *dm1105dvb = | 540 | struct dm1105_dev *dev = container_of(work, struct dm1105_dev, work); |
521 | container_of(work, struct dm1105dvb, work); | ||
522 | unsigned int nbpackets; | 541 | unsigned int nbpackets; |
523 | u32 oldwrp = dm1105dvb->wrp; | 542 | u32 oldwrp = dev->wrp; |
524 | u32 nextwrp = dm1105dvb->nextwrp; | 543 | u32 nextwrp = dev->nextwrp; |
525 | 544 | ||
526 | if (!((dm1105dvb->ts_buf[oldwrp] == 0x47) && | 545 | if (!((dev->ts_buf[oldwrp] == 0x47) && |
527 | (dm1105dvb->ts_buf[oldwrp + 188] == 0x47) && | 546 | (dev->ts_buf[oldwrp + 188] == 0x47) && |
528 | (dm1105dvb->ts_buf[oldwrp + 188 * 2] == 0x47))) { | 547 | (dev->ts_buf[oldwrp + 188 * 2] == 0x47))) { |
529 | dm1105dvb->PacketErrorCount++; | 548 | dev->PacketErrorCount++; |
530 | /* bad packet found */ | 549 | /* bad packet found */ |
531 | if ((dm1105dvb->PacketErrorCount >= 2) && | 550 | if ((dev->PacketErrorCount >= 2) && |
532 | (dm1105dvb->dmarst == 0)) { | 551 | (dev->dmarst == 0)) { |
533 | outb(1, dm_io_mem(DM1105_RST)); | 552 | dm_writeb(DM1105_RST, 1); |
534 | dm1105dvb->wrp = 0; | 553 | dev->wrp = 0; |
535 | dm1105dvb->PacketErrorCount = 0; | 554 | dev->PacketErrorCount = 0; |
536 | dm1105dvb->dmarst = 0; | 555 | dev->dmarst = 0; |
537 | return; | 556 | return; |
538 | } | 557 | } |
539 | } | 558 | } |
540 | 559 | ||
541 | if (nextwrp < oldwrp) { | 560 | if (nextwrp < oldwrp) { |
542 | memcpy(dm1105dvb->ts_buf + dm1105dvb->buffer_size, | 561 | memcpy(dev->ts_buf + dev->buffer_size, dev->ts_buf, nextwrp); |
543 | dm1105dvb->ts_buf, nextwrp); | 562 | nbpackets = ((dev->buffer_size - oldwrp) + nextwrp) / 188; |
544 | nbpackets = ((dm1105dvb->buffer_size - oldwrp) + nextwrp) / 188; | ||
545 | } else | 563 | } else |
546 | nbpackets = (nextwrp - oldwrp) / 188; | 564 | nbpackets = (nextwrp - oldwrp) / 188; |
547 | 565 | ||
548 | dm1105dvb->wrp = nextwrp; | 566 | dev->wrp = nextwrp; |
549 | dvb_dmx_swfilter_packets(&dm1105dvb->demux, | 567 | dvb_dmx_swfilter_packets(&dev->demux, &dev->ts_buf[oldwrp], nbpackets); |
550 | &dm1105dvb->ts_buf[oldwrp], nbpackets); | ||
551 | } | 568 | } |
552 | 569 | ||
553 | static irqreturn_t dm1105dvb_irq(int irq, void *dev_id) | 570 | static irqreturn_t dm1105_irq(int irq, void *dev_id) |
554 | { | 571 | { |
555 | struct dm1105dvb *dm1105dvb = dev_id; | 572 | struct dm1105_dev *dev = dev_id; |
556 | 573 | ||
557 | /* Read-Write INSTS Ack's Interrupt for DM1105 chip 16.03.2008 */ | 574 | /* Read-Write INSTS Ack's Interrupt for DM1105 chip 16.03.2008 */ |
558 | unsigned int intsts = inb(dm_io_mem(DM1105_INTSTS)); | 575 | unsigned int intsts = dm_readb(DM1105_INTSTS); |
559 | outb(intsts, dm_io_mem(DM1105_INTSTS)); | 576 | dm_writeb(DM1105_INTSTS, intsts); |
560 | 577 | ||
561 | switch (intsts) { | 578 | switch (intsts) { |
562 | case INTSTS_TSIRQ: | 579 | case INTSTS_TSIRQ: |
563 | case (INTSTS_TSIRQ | INTSTS_IR): | 580 | case (INTSTS_TSIRQ | INTSTS_IR): |
564 | dm1105dvb->nextwrp = inl(dm_io_mem(DM1105_WRP)) - | 581 | dev->nextwrp = dm_readl(DM1105_WRP) - dm_readl(DM1105_STADR); |
565 | inl(dm_io_mem(DM1105_STADR)); | 582 | queue_work(dev->wq, &dev->work); |
566 | queue_work(dm1105dvb->wq, &dm1105dvb->work); | ||
567 | break; | 583 | break; |
568 | case INTSTS_IR: | 584 | case INTSTS_IR: |
569 | dm1105dvb->ir.ir_command = inl(dm_io_mem(DM1105_IRCODE)); | 585 | dev->ir.ir_command = dm_readl(DM1105_IRCODE); |
570 | schedule_work(&dm1105dvb->ir.work); | 586 | schedule_work(&dev->ir.work); |
571 | break; | 587 | break; |
572 | } | 588 | } |
573 | 589 | ||
574 | return IRQ_HANDLED; | 590 | return IRQ_HANDLED; |
575 | } | 591 | } |
576 | 592 | ||
577 | int __devinit dm1105_ir_init(struct dm1105dvb *dm1105) | 593 | int __devinit dm1105_ir_init(struct dm1105_dev *dm1105) |
578 | { | 594 | { |
579 | struct input_dev *input_dev; | 595 | struct input_dev *input_dev; |
580 | struct ir_scancode_table *ir_codes = &ir_codes_dm1105_nec_table; | 596 | struct ir_scancode_table *ir_codes = &ir_codes_dm1105_nec_table; |
581 | int ir_type = IR_TYPE_OTHER; | 597 | u64 ir_type = IR_TYPE_OTHER; |
582 | int err = -ENOMEM; | 598 | int err = -ENOMEM; |
583 | 599 | ||
584 | input_dev = input_allocate_device(); | 600 | input_dev = input_allocate_device(); |
@@ -611,51 +627,51 @@ int __devinit dm1105_ir_init(struct dm1105dvb *dm1105) | |||
611 | 627 | ||
612 | INIT_WORK(&dm1105->ir.work, dm1105_emit_key); | 628 | INIT_WORK(&dm1105->ir.work, dm1105_emit_key); |
613 | 629 | ||
614 | err = ir_input_register(input_dev, ir_codes); | 630 | err = ir_input_register(input_dev, ir_codes, NULL); |
615 | 631 | ||
616 | return err; | 632 | return err; |
617 | } | 633 | } |
618 | 634 | ||
619 | void __devexit dm1105_ir_exit(struct dm1105dvb *dm1105) | 635 | void __devexit dm1105_ir_exit(struct dm1105_dev *dm1105) |
620 | { | 636 | { |
621 | ir_input_unregister(dm1105->ir.input_dev); | 637 | ir_input_unregister(dm1105->ir.input_dev); |
622 | } | 638 | } |
623 | 639 | ||
624 | static int __devinit dm1105dvb_hw_init(struct dm1105dvb *dm1105dvb) | 640 | static int __devinit dm1105_hw_init(struct dm1105_dev *dev) |
625 | { | 641 | { |
626 | dm1105dvb_disable_irqs(dm1105dvb); | 642 | dm1105_disable_irqs(dev); |
627 | 643 | ||
628 | outb(0, dm_io_mem(DM1105_HOST_CTR)); | 644 | dm_writeb(DM1105_HOST_CTR, 0); |
629 | 645 | ||
630 | /*DATALEN 188,*/ | 646 | /*DATALEN 188,*/ |
631 | outb(188, dm_io_mem(DM1105_DTALENTH)); | 647 | dm_writeb(DM1105_DTALENTH, 188); |
632 | /*TS_STRT TS_VALP MSBFIRST TS_MODE ALPAS TSPES*/ | 648 | /*TS_STRT TS_VALP MSBFIRST TS_MODE ALPAS TSPES*/ |
633 | outw(0xc10a, dm_io_mem(DM1105_TSCTR)); | 649 | dm_writew(DM1105_TSCTR, 0xc10a); |
634 | 650 | ||
635 | /* map DMA and set address */ | 651 | /* map DMA and set address */ |
636 | dm1105dvb_dma_map(dm1105dvb); | 652 | dm1105_dma_map(dev); |
637 | dm1105dvb_set_dma_addr(dm1105dvb); | 653 | dm1105_set_dma_addr(dev); |
638 | /* big buffer */ | 654 | /* big buffer */ |
639 | outl(5*DM1105_DMA_BYTES, dm_io_mem(DM1105_RLEN)); | 655 | dm_writel(DM1105_RLEN, 5 * DM1105_DMA_BYTES); |
640 | outb(47, dm_io_mem(DM1105_INTCNT)); | 656 | dm_writeb(DM1105_INTCNT, 47); |
641 | 657 | ||
642 | /* IR NEC mode enable */ | 658 | /* IR NEC mode enable */ |
643 | outb((DM1105_IR_EN | DM1105_SYS_CHK), dm_io_mem(DM1105_IRCTR)); | 659 | dm_writeb(DM1105_IRCTR, (DM1105_IR_EN | DM1105_SYS_CHK)); |
644 | outb(0, dm_io_mem(DM1105_IRMODE)); | 660 | dm_writeb(DM1105_IRMODE, 0); |
645 | outw(0, dm_io_mem(DM1105_SYSTEMCODE)); | 661 | dm_writew(DM1105_SYSTEMCODE, 0); |
646 | 662 | ||
647 | return 0; | 663 | return 0; |
648 | } | 664 | } |
649 | 665 | ||
650 | static void dm1105dvb_hw_exit(struct dm1105dvb *dm1105dvb) | 666 | static void dm1105_hw_exit(struct dm1105_dev *dev) |
651 | { | 667 | { |
652 | dm1105dvb_disable_irqs(dm1105dvb); | 668 | dm1105_disable_irqs(dev); |
653 | 669 | ||
654 | /* IR disable */ | 670 | /* IR disable */ |
655 | outb(0, dm_io_mem(DM1105_IRCTR)); | 671 | dm_writeb(DM1105_IRCTR, 0); |
656 | outb(INTMAK_NONEMASK, dm_io_mem(DM1105_INTMAK)); | 672 | dm_writeb(DM1105_INTMAK, INTMAK_NONEMASK); |
657 | 673 | ||
658 | dm1105dvb_dma_unmap(dm1105dvb); | 674 | dm1105_dma_unmap(dev); |
659 | } | 675 | } |
660 | 676 | ||
661 | static struct stv0299_config sharp_z0194a_config = { | 677 | static struct stv0299_config sharp_z0194a_config = { |
@@ -685,70 +701,79 @@ static struct cx24116_config serit_sp2633_config = { | |||
685 | .demod_address = 0x55, | 701 | .demod_address = 0x55, |
686 | }; | 702 | }; |
687 | 703 | ||
688 | static int __devinit frontend_init(struct dm1105dvb *dm1105dvb) | 704 | static struct ds3000_config dvbworld_ds3000_config = { |
705 | .demod_address = 0x68, | ||
706 | }; | ||
707 | |||
708 | static int __devinit frontend_init(struct dm1105_dev *dev) | ||
689 | { | 709 | { |
690 | int ret; | 710 | int ret; |
691 | 711 | ||
692 | switch (dm1105dvb->boardnr) { | 712 | switch (dev->boardnr) { |
693 | case DM1105_BOARD_DVBWORLD_2004: | 713 | case DM1105_BOARD_DVBWORLD_2004: |
694 | dm1105dvb->fe = dvb_attach( | 714 | dev->fe = dvb_attach( |
695 | cx24116_attach, &serit_sp2633_config, | 715 | cx24116_attach, &serit_sp2633_config, |
696 | &dm1105dvb->i2c_adap); | 716 | &dev->i2c_adap); |
697 | if (dm1105dvb->fe) | 717 | if (dev->fe) { |
698 | dm1105dvb->fe->ops.set_voltage = dm1105dvb_set_voltage; | 718 | dev->fe->ops.set_voltage = dm1105_set_voltage; |
719 | break; | ||
720 | } | ||
721 | |||
722 | dev->fe = dvb_attach( | ||
723 | ds3000_attach, &dvbworld_ds3000_config, | ||
724 | &dev->i2c_adap); | ||
725 | if (dev->fe) | ||
726 | dev->fe->ops.set_voltage = dm1105_set_voltage; | ||
699 | 727 | ||
700 | break; | 728 | break; |
701 | case DM1105_BOARD_DVBWORLD_2002: | 729 | case DM1105_BOARD_DVBWORLD_2002: |
702 | case DM1105_BOARD_AXESS_DM05: | 730 | case DM1105_BOARD_AXESS_DM05: |
703 | default: | 731 | default: |
704 | dm1105dvb->fe = dvb_attach( | 732 | dev->fe = dvb_attach( |
705 | stv0299_attach, &sharp_z0194a_config, | 733 | stv0299_attach, &sharp_z0194a_config, |
706 | &dm1105dvb->i2c_adap); | 734 | &dev->i2c_adap); |
707 | if (dm1105dvb->fe) { | 735 | if (dev->fe) { |
708 | dm1105dvb->fe->ops.set_voltage = | 736 | dev->fe->ops.set_voltage = dm1105_set_voltage; |
709 | dm1105dvb_set_voltage; | 737 | dvb_attach(dvb_pll_attach, dev->fe, 0x60, |
710 | dvb_attach(dvb_pll_attach, dm1105dvb->fe, 0x60, | 738 | &dev->i2c_adap, DVB_PLL_OPERA1); |
711 | &dm1105dvb->i2c_adap, DVB_PLL_OPERA1); | ||
712 | break; | 739 | break; |
713 | } | 740 | } |
714 | 741 | ||
715 | dm1105dvb->fe = dvb_attach( | 742 | dev->fe = dvb_attach( |
716 | stv0288_attach, &earda_config, | 743 | stv0288_attach, &earda_config, |
717 | &dm1105dvb->i2c_adap); | 744 | &dev->i2c_adap); |
718 | if (dm1105dvb->fe) { | 745 | if (dev->fe) { |
719 | dm1105dvb->fe->ops.set_voltage = | 746 | dev->fe->ops.set_voltage = dm1105_set_voltage; |
720 | dm1105dvb_set_voltage; | 747 | dvb_attach(stb6000_attach, dev->fe, 0x61, |
721 | dvb_attach(stb6000_attach, dm1105dvb->fe, 0x61, | 748 | &dev->i2c_adap); |
722 | &dm1105dvb->i2c_adap); | ||
723 | break; | 749 | break; |
724 | } | 750 | } |
725 | 751 | ||
726 | dm1105dvb->fe = dvb_attach( | 752 | dev->fe = dvb_attach( |
727 | si21xx_attach, &serit_config, | 753 | si21xx_attach, &serit_config, |
728 | &dm1105dvb->i2c_adap); | 754 | &dev->i2c_adap); |
729 | if (dm1105dvb->fe) | 755 | if (dev->fe) |
730 | dm1105dvb->fe->ops.set_voltage = | 756 | dev->fe->ops.set_voltage = dm1105_set_voltage; |
731 | dm1105dvb_set_voltage; | ||
732 | 757 | ||
733 | } | 758 | } |
734 | 759 | ||
735 | if (!dm1105dvb->fe) { | 760 | if (!dev->fe) { |
736 | dev_err(&dm1105dvb->pdev->dev, "could not attach frontend\n"); | 761 | dev_err(&dev->pdev->dev, "could not attach frontend\n"); |
737 | return -ENODEV; | 762 | return -ENODEV; |
738 | } | 763 | } |
739 | 764 | ||
740 | ret = dvb_register_frontend(&dm1105dvb->dvb_adapter, dm1105dvb->fe); | 765 | ret = dvb_register_frontend(&dev->dvb_adapter, dev->fe); |
741 | if (ret < 0) { | 766 | if (ret < 0) { |
742 | if (dm1105dvb->fe->ops.release) | 767 | if (dev->fe->ops.release) |
743 | dm1105dvb->fe->ops.release(dm1105dvb->fe); | 768 | dev->fe->ops.release(dev->fe); |
744 | dm1105dvb->fe = NULL; | 769 | dev->fe = NULL; |
745 | return ret; | 770 | return ret; |
746 | } | 771 | } |
747 | 772 | ||
748 | return 0; | 773 | return 0; |
749 | } | 774 | } |
750 | 775 | ||
751 | static void __devinit dm1105dvb_read_mac(struct dm1105dvb *dm1105dvb, u8 *mac) | 776 | static void __devinit dm1105_read_mac(struct dm1105_dev *dev, u8 *mac) |
752 | { | 777 | { |
753 | static u8 command[1] = { 0x28 }; | 778 | static u8 command[1] = { 0x28 }; |
754 | 779 | ||
@@ -766,47 +791,47 @@ static void __devinit dm1105dvb_read_mac(struct dm1105dvb *dm1105dvb, u8 *mac) | |||
766 | }, | 791 | }, |
767 | }; | 792 | }; |
768 | 793 | ||
769 | dm1105_i2c_xfer(&dm1105dvb->i2c_adap, msg , 2); | 794 | dm1105_i2c_xfer(&dev->i2c_adap, msg , 2); |
770 | dev_info(&dm1105dvb->pdev->dev, "MAC %pM\n", mac); | 795 | dev_info(&dev->pdev->dev, "MAC %pM\n", mac); |
771 | } | 796 | } |
772 | 797 | ||
773 | static int __devinit dm1105_probe(struct pci_dev *pdev, | 798 | static int __devinit dm1105_probe(struct pci_dev *pdev, |
774 | const struct pci_device_id *ent) | 799 | const struct pci_device_id *ent) |
775 | { | 800 | { |
776 | struct dm1105dvb *dm1105dvb; | 801 | struct dm1105_dev *dev; |
777 | struct dvb_adapter *dvb_adapter; | 802 | struct dvb_adapter *dvb_adapter; |
778 | struct dvb_demux *dvbdemux; | 803 | struct dvb_demux *dvbdemux; |
779 | struct dmx_demux *dmx; | 804 | struct dmx_demux *dmx; |
780 | int ret = -ENOMEM; | 805 | int ret = -ENOMEM; |
781 | int i; | 806 | int i; |
782 | 807 | ||
783 | dm1105dvb = kzalloc(sizeof(struct dm1105dvb), GFP_KERNEL); | 808 | dev = kzalloc(sizeof(struct dm1105_dev), GFP_KERNEL); |
784 | if (!dm1105dvb) | 809 | if (!dev) |
785 | return -ENOMEM; | 810 | return -ENOMEM; |
786 | 811 | ||
787 | /* board config */ | 812 | /* board config */ |
788 | dm1105dvb->nr = dm1105_devcount; | 813 | dev->nr = dm1105_devcount; |
789 | dm1105dvb->boardnr = UNSET; | 814 | dev->boardnr = UNSET; |
790 | if (card[dm1105dvb->nr] < ARRAY_SIZE(dm1105_boards)) | 815 | if (card[dev->nr] < ARRAY_SIZE(dm1105_boards)) |
791 | dm1105dvb->boardnr = card[dm1105dvb->nr]; | 816 | dev->boardnr = card[dev->nr]; |
792 | for (i = 0; UNSET == dm1105dvb->boardnr && | 817 | for (i = 0; UNSET == dev->boardnr && |
793 | i < ARRAY_SIZE(dm1105_subids); i++) | 818 | i < ARRAY_SIZE(dm1105_subids); i++) |
794 | if (pdev->subsystem_vendor == | 819 | if (pdev->subsystem_vendor == |
795 | dm1105_subids[i].subvendor && | 820 | dm1105_subids[i].subvendor && |
796 | pdev->subsystem_device == | 821 | pdev->subsystem_device == |
797 | dm1105_subids[i].subdevice) | 822 | dm1105_subids[i].subdevice) |
798 | dm1105dvb->boardnr = dm1105_subids[i].card; | 823 | dev->boardnr = dm1105_subids[i].card; |
799 | 824 | ||
800 | if (UNSET == dm1105dvb->boardnr) { | 825 | if (UNSET == dev->boardnr) { |
801 | dm1105dvb->boardnr = DM1105_BOARD_UNKNOWN; | 826 | dev->boardnr = DM1105_BOARD_UNKNOWN; |
802 | dm1105_card_list(pdev); | 827 | dm1105_card_list(pdev); |
803 | } | 828 | } |
804 | 829 | ||
805 | dm1105_devcount++; | 830 | dm1105_devcount++; |
806 | dm1105dvb->pdev = pdev; | 831 | dev->pdev = pdev; |
807 | dm1105dvb->buffer_size = 5 * DM1105_DMA_BYTES; | 832 | dev->buffer_size = 5 * DM1105_DMA_BYTES; |
808 | dm1105dvb->PacketErrorCount = 0; | 833 | dev->PacketErrorCount = 0; |
809 | dm1105dvb->dmarst = 0; | 834 | dev->dmarst = 0; |
810 | 835 | ||
811 | ret = pci_enable_device(pdev); | 836 | ret = pci_enable_device(pdev); |
812 | if (ret < 0) | 837 | if (ret < 0) |
@@ -822,47 +847,47 @@ static int __devinit dm1105_probe(struct pci_dev *pdev, | |||
822 | if (ret < 0) | 847 | if (ret < 0) |
823 | goto err_pci_disable_device; | 848 | goto err_pci_disable_device; |
824 | 849 | ||
825 | dm1105dvb->io_mem = pci_iomap(pdev, 0, pci_resource_len(pdev, 0)); | 850 | dev->io_mem = pci_iomap(pdev, 0, pci_resource_len(pdev, 0)); |
826 | if (!dm1105dvb->io_mem) { | 851 | if (!dev->io_mem) { |
827 | ret = -EIO; | 852 | ret = -EIO; |
828 | goto err_pci_release_regions; | 853 | goto err_pci_release_regions; |
829 | } | 854 | } |
830 | 855 | ||
831 | spin_lock_init(&dm1105dvb->lock); | 856 | spin_lock_init(&dev->lock); |
832 | pci_set_drvdata(pdev, dm1105dvb); | 857 | pci_set_drvdata(pdev, dev); |
833 | 858 | ||
834 | ret = dm1105dvb_hw_init(dm1105dvb); | 859 | ret = dm1105_hw_init(dev); |
835 | if (ret < 0) | 860 | if (ret < 0) |
836 | goto err_pci_iounmap; | 861 | goto err_pci_iounmap; |
837 | 862 | ||
838 | /* i2c */ | 863 | /* i2c */ |
839 | i2c_set_adapdata(&dm1105dvb->i2c_adap, dm1105dvb); | 864 | i2c_set_adapdata(&dev->i2c_adap, dev); |
840 | strcpy(dm1105dvb->i2c_adap.name, DRIVER_NAME); | 865 | strcpy(dev->i2c_adap.name, DRIVER_NAME); |
841 | dm1105dvb->i2c_adap.owner = THIS_MODULE; | 866 | dev->i2c_adap.owner = THIS_MODULE; |
842 | dm1105dvb->i2c_adap.class = I2C_CLASS_TV_DIGITAL; | 867 | dev->i2c_adap.class = I2C_CLASS_TV_DIGITAL; |
843 | dm1105dvb->i2c_adap.dev.parent = &pdev->dev; | 868 | dev->i2c_adap.dev.parent = &pdev->dev; |
844 | dm1105dvb->i2c_adap.algo = &dm1105_algo; | 869 | dev->i2c_adap.algo = &dm1105_algo; |
845 | dm1105dvb->i2c_adap.algo_data = dm1105dvb; | 870 | dev->i2c_adap.algo_data = dev; |
846 | ret = i2c_add_adapter(&dm1105dvb->i2c_adap); | 871 | ret = i2c_add_adapter(&dev->i2c_adap); |
847 | 872 | ||
848 | if (ret < 0) | 873 | if (ret < 0) |
849 | goto err_dm1105dvb_hw_exit; | 874 | goto err_dm1105_hw_exit; |
850 | 875 | ||
851 | /* dvb */ | 876 | /* dvb */ |
852 | ret = dvb_register_adapter(&dm1105dvb->dvb_adapter, DRIVER_NAME, | 877 | ret = dvb_register_adapter(&dev->dvb_adapter, DRIVER_NAME, |
853 | THIS_MODULE, &pdev->dev, adapter_nr); | 878 | THIS_MODULE, &pdev->dev, adapter_nr); |
854 | if (ret < 0) | 879 | if (ret < 0) |
855 | goto err_i2c_del_adapter; | 880 | goto err_i2c_del_adapter; |
856 | 881 | ||
857 | dvb_adapter = &dm1105dvb->dvb_adapter; | 882 | dvb_adapter = &dev->dvb_adapter; |
858 | 883 | ||
859 | dm1105dvb_read_mac(dm1105dvb, dvb_adapter->proposed_mac); | 884 | dm1105_read_mac(dev, dvb_adapter->proposed_mac); |
860 | 885 | ||
861 | dvbdemux = &dm1105dvb->demux; | 886 | dvbdemux = &dev->demux; |
862 | dvbdemux->filternum = 256; | 887 | dvbdemux->filternum = 256; |
863 | dvbdemux->feednum = 256; | 888 | dvbdemux->feednum = 256; |
864 | dvbdemux->start_feed = dm1105dvb_start_feed; | 889 | dvbdemux->start_feed = dm1105_start_feed; |
865 | dvbdemux->stop_feed = dm1105dvb_stop_feed; | 890 | dvbdemux->stop_feed = dm1105_stop_feed; |
866 | dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | | 891 | dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | |
867 | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING); | 892 | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING); |
868 | ret = dvb_dmx_init(dvbdemux); | 893 | ret = dvb_dmx_init(dvbdemux); |
@@ -870,113 +895,113 @@ static int __devinit dm1105_probe(struct pci_dev *pdev, | |||
870 | goto err_dvb_unregister_adapter; | 895 | goto err_dvb_unregister_adapter; |
871 | 896 | ||
872 | dmx = &dvbdemux->dmx; | 897 | dmx = &dvbdemux->dmx; |
873 | dm1105dvb->dmxdev.filternum = 256; | 898 | dev->dmxdev.filternum = 256; |
874 | dm1105dvb->dmxdev.demux = dmx; | 899 | dev->dmxdev.demux = dmx; |
875 | dm1105dvb->dmxdev.capabilities = 0; | 900 | dev->dmxdev.capabilities = 0; |
876 | 901 | ||
877 | ret = dvb_dmxdev_init(&dm1105dvb->dmxdev, dvb_adapter); | 902 | ret = dvb_dmxdev_init(&dev->dmxdev, dvb_adapter); |
878 | if (ret < 0) | 903 | if (ret < 0) |
879 | goto err_dvb_dmx_release; | 904 | goto err_dvb_dmx_release; |
880 | 905 | ||
881 | dm1105dvb->hw_frontend.source = DMX_FRONTEND_0; | 906 | dev->hw_frontend.source = DMX_FRONTEND_0; |
882 | 907 | ||
883 | ret = dmx->add_frontend(dmx, &dm1105dvb->hw_frontend); | 908 | ret = dmx->add_frontend(dmx, &dev->hw_frontend); |
884 | if (ret < 0) | 909 | if (ret < 0) |
885 | goto err_dvb_dmxdev_release; | 910 | goto err_dvb_dmxdev_release; |
886 | 911 | ||
887 | dm1105dvb->mem_frontend.source = DMX_MEMORY_FE; | 912 | dev->mem_frontend.source = DMX_MEMORY_FE; |
888 | 913 | ||
889 | ret = dmx->add_frontend(dmx, &dm1105dvb->mem_frontend); | 914 | ret = dmx->add_frontend(dmx, &dev->mem_frontend); |
890 | if (ret < 0) | 915 | if (ret < 0) |
891 | goto err_remove_hw_frontend; | 916 | goto err_remove_hw_frontend; |
892 | 917 | ||
893 | ret = dmx->connect_frontend(dmx, &dm1105dvb->hw_frontend); | 918 | ret = dmx->connect_frontend(dmx, &dev->hw_frontend); |
894 | if (ret < 0) | 919 | if (ret < 0) |
895 | goto err_remove_mem_frontend; | 920 | goto err_remove_mem_frontend; |
896 | 921 | ||
897 | ret = frontend_init(dm1105dvb); | 922 | ret = frontend_init(dev); |
898 | if (ret < 0) | 923 | if (ret < 0) |
899 | goto err_disconnect_frontend; | 924 | goto err_disconnect_frontend; |
900 | 925 | ||
901 | dvb_net_init(dvb_adapter, &dm1105dvb->dvbnet, dmx); | 926 | dvb_net_init(dvb_adapter, &dev->dvbnet, dmx); |
902 | dm1105_ir_init(dm1105dvb); | 927 | dm1105_ir_init(dev); |
903 | 928 | ||
904 | INIT_WORK(&dm1105dvb->work, dm1105_dmx_buffer); | 929 | INIT_WORK(&dev->work, dm1105_dmx_buffer); |
905 | sprintf(dm1105dvb->wqn, "%s/%d", dvb_adapter->name, dvb_adapter->num); | 930 | sprintf(dev->wqn, "%s/%d", dvb_adapter->name, dvb_adapter->num); |
906 | dm1105dvb->wq = create_singlethread_workqueue(dm1105dvb->wqn); | 931 | dev->wq = create_singlethread_workqueue(dev->wqn); |
907 | if (!dm1105dvb->wq) | 932 | if (!dev->wq) |
908 | goto err_dvb_net; | 933 | goto err_dvb_net; |
909 | 934 | ||
910 | ret = request_irq(pdev->irq, dm1105dvb_irq, IRQF_SHARED, | 935 | ret = request_irq(pdev->irq, dm1105_irq, IRQF_SHARED, |
911 | DRIVER_NAME, dm1105dvb); | 936 | DRIVER_NAME, dev); |
912 | if (ret < 0) | 937 | if (ret < 0) |
913 | goto err_workqueue; | 938 | goto err_workqueue; |
914 | 939 | ||
915 | return 0; | 940 | return 0; |
916 | 941 | ||
917 | err_workqueue: | 942 | err_workqueue: |
918 | destroy_workqueue(dm1105dvb->wq); | 943 | destroy_workqueue(dev->wq); |
919 | err_dvb_net: | 944 | err_dvb_net: |
920 | dvb_net_release(&dm1105dvb->dvbnet); | 945 | dvb_net_release(&dev->dvbnet); |
921 | err_disconnect_frontend: | 946 | err_disconnect_frontend: |
922 | dmx->disconnect_frontend(dmx); | 947 | dmx->disconnect_frontend(dmx); |
923 | err_remove_mem_frontend: | 948 | err_remove_mem_frontend: |
924 | dmx->remove_frontend(dmx, &dm1105dvb->mem_frontend); | 949 | dmx->remove_frontend(dmx, &dev->mem_frontend); |
925 | err_remove_hw_frontend: | 950 | err_remove_hw_frontend: |
926 | dmx->remove_frontend(dmx, &dm1105dvb->hw_frontend); | 951 | dmx->remove_frontend(dmx, &dev->hw_frontend); |
927 | err_dvb_dmxdev_release: | 952 | err_dvb_dmxdev_release: |
928 | dvb_dmxdev_release(&dm1105dvb->dmxdev); | 953 | dvb_dmxdev_release(&dev->dmxdev); |
929 | err_dvb_dmx_release: | 954 | err_dvb_dmx_release: |
930 | dvb_dmx_release(dvbdemux); | 955 | dvb_dmx_release(dvbdemux); |
931 | err_dvb_unregister_adapter: | 956 | err_dvb_unregister_adapter: |
932 | dvb_unregister_adapter(dvb_adapter); | 957 | dvb_unregister_adapter(dvb_adapter); |
933 | err_i2c_del_adapter: | 958 | err_i2c_del_adapter: |
934 | i2c_del_adapter(&dm1105dvb->i2c_adap); | 959 | i2c_del_adapter(&dev->i2c_adap); |
935 | err_dm1105dvb_hw_exit: | 960 | err_dm1105_hw_exit: |
936 | dm1105dvb_hw_exit(dm1105dvb); | 961 | dm1105_hw_exit(dev); |
937 | err_pci_iounmap: | 962 | err_pci_iounmap: |
938 | pci_iounmap(pdev, dm1105dvb->io_mem); | 963 | pci_iounmap(pdev, dev->io_mem); |
939 | err_pci_release_regions: | 964 | err_pci_release_regions: |
940 | pci_release_regions(pdev); | 965 | pci_release_regions(pdev); |
941 | err_pci_disable_device: | 966 | err_pci_disable_device: |
942 | pci_disable_device(pdev); | 967 | pci_disable_device(pdev); |
943 | err_kfree: | 968 | err_kfree: |
944 | pci_set_drvdata(pdev, NULL); | 969 | pci_set_drvdata(pdev, NULL); |
945 | kfree(dm1105dvb); | 970 | kfree(dev); |
946 | return ret; | 971 | return ret; |
947 | } | 972 | } |
948 | 973 | ||
949 | static void __devexit dm1105_remove(struct pci_dev *pdev) | 974 | static void __devexit dm1105_remove(struct pci_dev *pdev) |
950 | { | 975 | { |
951 | struct dm1105dvb *dm1105dvb = pci_get_drvdata(pdev); | 976 | struct dm1105_dev *dev = pci_get_drvdata(pdev); |
952 | struct dvb_adapter *dvb_adapter = &dm1105dvb->dvb_adapter; | 977 | struct dvb_adapter *dvb_adapter = &dev->dvb_adapter; |
953 | struct dvb_demux *dvbdemux = &dm1105dvb->demux; | 978 | struct dvb_demux *dvbdemux = &dev->demux; |
954 | struct dmx_demux *dmx = &dvbdemux->dmx; | 979 | struct dmx_demux *dmx = &dvbdemux->dmx; |
955 | 980 | ||
956 | dm1105_ir_exit(dm1105dvb); | 981 | dm1105_ir_exit(dev); |
957 | dmx->close(dmx); | 982 | dmx->close(dmx); |
958 | dvb_net_release(&dm1105dvb->dvbnet); | 983 | dvb_net_release(&dev->dvbnet); |
959 | if (dm1105dvb->fe) | 984 | if (dev->fe) |
960 | dvb_unregister_frontend(dm1105dvb->fe); | 985 | dvb_unregister_frontend(dev->fe); |
961 | 986 | ||
962 | dmx->disconnect_frontend(dmx); | 987 | dmx->disconnect_frontend(dmx); |
963 | dmx->remove_frontend(dmx, &dm1105dvb->mem_frontend); | 988 | dmx->remove_frontend(dmx, &dev->mem_frontend); |
964 | dmx->remove_frontend(dmx, &dm1105dvb->hw_frontend); | 989 | dmx->remove_frontend(dmx, &dev->hw_frontend); |
965 | dvb_dmxdev_release(&dm1105dvb->dmxdev); | 990 | dvb_dmxdev_release(&dev->dmxdev); |
966 | dvb_dmx_release(dvbdemux); | 991 | dvb_dmx_release(dvbdemux); |
967 | dvb_unregister_adapter(dvb_adapter); | 992 | dvb_unregister_adapter(dvb_adapter); |
968 | if (&dm1105dvb->i2c_adap) | 993 | if (&dev->i2c_adap) |
969 | i2c_del_adapter(&dm1105dvb->i2c_adap); | 994 | i2c_del_adapter(&dev->i2c_adap); |
970 | 995 | ||
971 | dm1105dvb_hw_exit(dm1105dvb); | 996 | dm1105_hw_exit(dev); |
972 | synchronize_irq(pdev->irq); | 997 | synchronize_irq(pdev->irq); |
973 | free_irq(pdev->irq, dm1105dvb); | 998 | free_irq(pdev->irq, dev); |
974 | pci_iounmap(pdev, dm1105dvb->io_mem); | 999 | pci_iounmap(pdev, dev->io_mem); |
975 | pci_release_regions(pdev); | 1000 | pci_release_regions(pdev); |
976 | pci_disable_device(pdev); | 1001 | pci_disable_device(pdev); |
977 | pci_set_drvdata(pdev, NULL); | 1002 | pci_set_drvdata(pdev, NULL); |
978 | dm1105_devcount--; | 1003 | dm1105_devcount--; |
979 | kfree(dm1105dvb); | 1004 | kfree(dev); |
980 | } | 1005 | } |
981 | 1006 | ||
982 | static struct pci_device_id dm1105_id_table[] __devinitdata = { | 1007 | static struct pci_device_id dm1105_id_table[] __devinitdata = { |
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index 07461222a7f5..55ea260572bf 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c | |||
@@ -1199,8 +1199,6 @@ static int dtv_property_process_get(struct dvb_frontend *fe, | |||
1199 | { | 1199 | { |
1200 | int r = 0; | 1200 | int r = 0; |
1201 | 1201 | ||
1202 | dtv_property_dump(tvp); | ||
1203 | |||
1204 | /* Allow the frontend to validate incoming properties */ | 1202 | /* Allow the frontend to validate incoming properties */ |
1205 | if (fe->ops.get_property) | 1203 | if (fe->ops.get_property) |
1206 | r = fe->ops.get_property(fe, tvp); | 1204 | r = fe->ops.get_property(fe, tvp); |
@@ -1323,6 +1321,8 @@ static int dtv_property_process_get(struct dvb_frontend *fe, | |||
1323 | r = -1; | 1321 | r = -1; |
1324 | } | 1322 | } |
1325 | 1323 | ||
1324 | dtv_property_dump(tvp); | ||
1325 | |||
1326 | return r; | 1326 | return r; |
1327 | } | 1327 | } |
1328 | 1328 | ||
@@ -1488,7 +1488,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
1488 | struct dvb_frontend_private *fepriv = fe->frontend_priv; | 1488 | struct dvb_frontend_private *fepriv = fe->frontend_priv; |
1489 | int err = -EOPNOTSUPP; | 1489 | int err = -EOPNOTSUPP; |
1490 | 1490 | ||
1491 | dprintk ("%s\n", __func__); | 1491 | dprintk("%s (%d)\n", __func__, _IOC_NR(cmd)); |
1492 | 1492 | ||
1493 | if (fepriv->exit) | 1493 | if (fepriv->exit) |
1494 | return -ENODEV; | 1494 | return -ENODEV; |
@@ -1536,8 +1536,7 @@ static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file, | |||
1536 | if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS)) | 1536 | if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS)) |
1537 | return -EINVAL; | 1537 | return -EINVAL; |
1538 | 1538 | ||
1539 | tvp = (struct dtv_property *) kmalloc(tvps->num * | 1539 | tvp = kmalloc(tvps->num * sizeof(struct dtv_property), GFP_KERNEL); |
1540 | sizeof(struct dtv_property), GFP_KERNEL); | ||
1541 | if (!tvp) { | 1540 | if (!tvp) { |
1542 | err = -ENOMEM; | 1541 | err = -ENOMEM; |
1543 | goto out; | 1542 | goto out; |
@@ -1569,8 +1568,7 @@ static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file, | |||
1569 | if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS)) | 1568 | if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS)) |
1570 | return -EINVAL; | 1569 | return -EINVAL; |
1571 | 1570 | ||
1572 | tvp = (struct dtv_property *) kmalloc(tvps->num * | 1571 | tvp = kmalloc(tvps->num * sizeof(struct dtv_property), GFP_KERNEL); |
1573 | sizeof(struct dtv_property), GFP_KERNEL); | ||
1574 | if (!tvp) { | 1572 | if (!tvp) { |
1575 | err = -ENOMEM; | 1573 | err = -ENOMEM; |
1576 | goto out; | 1574 | goto out; |
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c index 37d8579fc7a9..441c0642b30a 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.c +++ b/drivers/media/dvb/dvb-core/dvb_net.c | |||
@@ -504,6 +504,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) | |||
504 | "bytes left in TS. Resyncing.\n", ts_remain); | 504 | "bytes left in TS. Resyncing.\n", ts_remain); |
505 | priv->ule_sndu_len = 0; | 505 | priv->ule_sndu_len = 0; |
506 | priv->need_pusi = 1; | 506 | priv->need_pusi = 1; |
507 | ts += TS_SZ; | ||
507 | continue; | 508 | continue; |
508 | } | 509 | } |
509 | 510 | ||
diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c index 584bbd194dc8..a5712cd7c65f 100644 --- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c +++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c | |||
@@ -89,6 +89,7 @@ void dvb_ringbuffer_flush(struct dvb_ringbuffer *rbuf) | |||
89 | rbuf->pread = rbuf->pwrite; | 89 | rbuf->pread = rbuf->pwrite; |
90 | rbuf->error = 0; | 90 | rbuf->error = 0; |
91 | } | 91 | } |
92 | EXPORT_SYMBOL(dvb_ringbuffer_flush); | ||
92 | 93 | ||
93 | void dvb_ringbuffer_reset(struct dvb_ringbuffer *rbuf) | 94 | void dvb_ringbuffer_reset(struct dvb_ringbuffer *rbuf) |
94 | { | 95 | { |
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 1b249897c9fb..e5f91f16ffa4 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig | |||
@@ -112,11 +112,13 @@ config DVB_USB_CXUSB | |||
112 | select DVB_MT352 if !DVB_FE_CUSTOMISE | 112 | select DVB_MT352 if !DVB_FE_CUSTOMISE |
113 | select DVB_ZL10353 if !DVB_FE_CUSTOMISE | 113 | select DVB_ZL10353 if !DVB_FE_CUSTOMISE |
114 | select DVB_DIB7000P if !DVB_FE_CUSTOMISE | 114 | select DVB_DIB7000P if !DVB_FE_CUSTOMISE |
115 | select DVB_LGS8GL5 if !DVB_FE_CUSTOMISE | ||
116 | select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE | 115 | select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE |
116 | select DVB_ATBM8830 if !DVB_FE_CUSTOMISE | ||
117 | select DVB_LGS8GXX if !DVB_FE_CUSTOMISE | ||
117 | select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE | 118 | select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE |
118 | select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE | 119 | select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE |
119 | select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE | 120 | select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE |
121 | select MEDIA_TUNER_MAX2165 if !MEDIA_TUNER_CUSTOMISE | ||
120 | help | 122 | help |
121 | Say Y here to support the Conexant USB2.0 hybrid reference design. | 123 | Say Y here to support the Conexant USB2.0 hybrid reference design. |
122 | Currently, only DVB and ATSC modes are supported, analog mode | 124 | Currently, only DVB and ATSC modes are supported, analog mode |
@@ -334,3 +336,11 @@ config DVB_USB_EC168 | |||
334 | select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE | 336 | select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE |
335 | help | 337 | help |
336 | Say Y here to support the E3C EC168 DVB-T USB2.0 receiver. | 338 | Say Y here to support the E3C EC168 DVB-T USB2.0 receiver. |
339 | |||
340 | config DVB_USB_AZ6027 | ||
341 | tristate "Azurewave DVB-S/S2 USB2.0 AZ6027 support" | ||
342 | depends on DVB_USB | ||
343 | select DVB_STB0899 if !DVB_FE_CUSTOMISE | ||
344 | select DVB_STB6100 if !DVB_FE_CUSTOMISE | ||
345 | help | ||
346 | Say Y here to support the AZ6027 device | ||
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile index 72c92cb69a22..1a192453b0e7 100644 --- a/drivers/media/dvb/dvb-usb/Makefile +++ b/drivers/media/dvb/dvb-usb/Makefile | |||
@@ -85,6 +85,9 @@ obj-$(CONFIG_DVB_USB_FRIIO) += dvb-usb-friio.o | |||
85 | dvb-usb-ec168-objs = ec168.o | 85 | dvb-usb-ec168-objs = ec168.o |
86 | obj-$(CONFIG_DVB_USB_EC168) += dvb-usb-ec168.o | 86 | obj-$(CONFIG_DVB_USB_EC168) += dvb-usb-ec168.o |
87 | 87 | ||
88 | dvb-usb-az6027-objs = az6027.o | ||
89 | obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o | ||
90 | |||
88 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ | 91 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ |
89 | # due to tuner-xc3028 | 92 | # due to tuner-xc3028 |
90 | EXTRA_CFLAGS += -Idrivers/media/common/tuners | 93 | EXTRA_CFLAGS += -Idrivers/media/common/tuners |
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c index 8b60a601fb82..d7975383d31b 100644 --- a/drivers/media/dvb/dvb-usb/af9015.c +++ b/drivers/media/dvb/dvb-usb/af9015.c | |||
@@ -21,6 +21,8 @@ | |||
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include <linux/hash.h> | ||
25 | |||
24 | #include "af9015.h" | 26 | #include "af9015.h" |
25 | #include "af9013.h" | 27 | #include "af9013.h" |
26 | #include "mt2060.h" | 28 | #include "mt2060.h" |
@@ -553,26 +555,45 @@ exit: | |||
553 | return ret; | 555 | return ret; |
554 | } | 556 | } |
555 | 557 | ||
556 | /* dump eeprom */ | 558 | /* hash (and dump) eeprom */ |
557 | static int af9015_eeprom_dump(struct dvb_usb_device *d) | 559 | static int af9015_eeprom_hash(struct usb_device *udev) |
558 | { | 560 | { |
559 | u8 reg, val; | 561 | static const unsigned int eeprom_size = 256; |
562 | unsigned int reg; | ||
563 | int ret; | ||
564 | u8 val, *eeprom; | ||
565 | struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val}; | ||
560 | 566 | ||
561 | for (reg = 0; ; reg++) { | 567 | eeprom = kmalloc(eeprom_size, GFP_KERNEL); |
562 | if (reg % 16 == 0) { | 568 | if (eeprom == NULL) |
563 | if (reg) | 569 | return -ENOMEM; |
564 | deb_info(KERN_CONT "\n"); | 570 | |
565 | deb_info(KERN_DEBUG "%02x:", reg); | 571 | for (reg = 0; reg < eeprom_size; reg++) { |
566 | } | 572 | req.addr = reg; |
567 | if (af9015_read_reg_i2c(d, AF9015_I2C_EEPROM, reg, &val) == 0) | 573 | ret = af9015_rw_udev(udev, &req); |
568 | deb_info(KERN_CONT " %02x", val); | 574 | if (ret) |
569 | else | 575 | goto free; |
570 | deb_info(KERN_CONT " --"); | 576 | eeprom[reg] = val; |
571 | if (reg == 0xff) | ||
572 | break; | ||
573 | } | 577 | } |
574 | deb_info(KERN_CONT "\n"); | 578 | |
575 | return 0; | 579 | if (dvb_usb_af9015_debug & 0x01) |
580 | print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, eeprom, | ||
581 | eeprom_size); | ||
582 | |||
583 | BUG_ON(eeprom_size % 4); | ||
584 | |||
585 | af9015_config.eeprom_sum = 0; | ||
586 | for (reg = 0; reg < eeprom_size / sizeof(u32); reg++) { | ||
587 | af9015_config.eeprom_sum *= GOLDEN_RATIO_PRIME_32; | ||
588 | af9015_config.eeprom_sum += le32_to_cpu(((u32 *)eeprom)[reg]); | ||
589 | } | ||
590 | |||
591 | deb_info("%s: eeprom sum=%.8x\n", __func__, af9015_config.eeprom_sum); | ||
592 | |||
593 | ret = 0; | ||
594 | free: | ||
595 | kfree(eeprom); | ||
596 | return ret; | ||
576 | } | 597 | } |
577 | 598 | ||
578 | static int af9015_download_ir_table(struct dvb_usb_device *d) | 599 | static int af9015_download_ir_table(struct dvb_usb_device *d) |
@@ -711,12 +732,132 @@ error: | |||
711 | return ret; | 732 | return ret; |
712 | } | 733 | } |
713 | 734 | ||
735 | struct af9015_setup { | ||
736 | unsigned int id; | ||
737 | struct dvb_usb_rc_key *rc_key_map; | ||
738 | unsigned int rc_key_map_size; | ||
739 | u8 *ir_table; | ||
740 | unsigned int ir_table_size; | ||
741 | }; | ||
742 | |||
743 | static const struct af9015_setup *af9015_setup_match(unsigned int id, | ||
744 | const struct af9015_setup *table) | ||
745 | { | ||
746 | for (; table->rc_key_map; table++) | ||
747 | if (table->id == id) | ||
748 | return table; | ||
749 | return NULL; | ||
750 | } | ||
751 | |||
752 | static const struct af9015_setup af9015_setup_modparam[] = { | ||
753 | { AF9015_REMOTE_A_LINK_DTU_M, | ||
754 | af9015_rc_keys_a_link, ARRAY_SIZE(af9015_rc_keys_a_link), | ||
755 | af9015_ir_table_a_link, ARRAY_SIZE(af9015_ir_table_a_link) }, | ||
756 | { AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, | ||
757 | af9015_rc_keys_msi, ARRAY_SIZE(af9015_rc_keys_msi), | ||
758 | af9015_ir_table_msi, ARRAY_SIZE(af9015_ir_table_msi) }, | ||
759 | { AF9015_REMOTE_MYGICTV_U718, | ||
760 | af9015_rc_keys_mygictv, ARRAY_SIZE(af9015_rc_keys_mygictv), | ||
761 | af9015_ir_table_mygictv, ARRAY_SIZE(af9015_ir_table_mygictv) }, | ||
762 | { AF9015_REMOTE_DIGITTRADE_DVB_T, | ||
763 | af9015_rc_keys_digittrade, ARRAY_SIZE(af9015_rc_keys_digittrade), | ||
764 | af9015_ir_table_digittrade, ARRAY_SIZE(af9015_ir_table_digittrade) }, | ||
765 | { AF9015_REMOTE_AVERMEDIA_KS, | ||
766 | af9015_rc_keys_avermedia, ARRAY_SIZE(af9015_rc_keys_avermedia), | ||
767 | af9015_ir_table_avermedia_ks, ARRAY_SIZE(af9015_ir_table_avermedia_ks) }, | ||
768 | { } | ||
769 | }; | ||
770 | |||
771 | /* don't add new entries here anymore, use hashes instead */ | ||
772 | static const struct af9015_setup af9015_setup_usbids[] = { | ||
773 | { USB_VID_LEADTEK, | ||
774 | af9015_rc_keys_leadtek, ARRAY_SIZE(af9015_rc_keys_leadtek), | ||
775 | af9015_ir_table_leadtek, ARRAY_SIZE(af9015_ir_table_leadtek) }, | ||
776 | { USB_VID_VISIONPLUS, | ||
777 | af9015_rc_keys_twinhan, ARRAY_SIZE(af9015_rc_keys_twinhan), | ||
778 | af9015_ir_table_twinhan, ARRAY_SIZE(af9015_ir_table_twinhan) }, | ||
779 | { USB_VID_KWORLD_2, /* TODO: use correct rc keys */ | ||
780 | af9015_rc_keys_twinhan, ARRAY_SIZE(af9015_rc_keys_twinhan), | ||
781 | af9015_ir_table_kworld, ARRAY_SIZE(af9015_ir_table_kworld) }, | ||
782 | { USB_VID_AVERMEDIA, | ||
783 | af9015_rc_keys_avermedia, ARRAY_SIZE(af9015_rc_keys_avermedia), | ||
784 | af9015_ir_table_avermedia, ARRAY_SIZE(af9015_ir_table_avermedia) }, | ||
785 | { USB_VID_MSI_2, | ||
786 | af9015_rc_keys_msi_digivox_iii, ARRAY_SIZE(af9015_rc_keys_msi_digivox_iii), | ||
787 | af9015_ir_table_msi_digivox_iii, ARRAY_SIZE(af9015_ir_table_msi_digivox_iii) }, | ||
788 | { } | ||
789 | }; | ||
790 | |||
791 | static const struct af9015_setup af9015_setup_hashes[] = { | ||
792 | { 0xb8feb708, | ||
793 | af9015_rc_keys_msi, ARRAY_SIZE(af9015_rc_keys_msi), | ||
794 | af9015_ir_table_msi, ARRAY_SIZE(af9015_ir_table_msi) }, | ||
795 | { 0xa3703d00, | ||
796 | af9015_rc_keys_a_link, ARRAY_SIZE(af9015_rc_keys_a_link), | ||
797 | af9015_ir_table_a_link, ARRAY_SIZE(af9015_ir_table_a_link) }, | ||
798 | { 0x9b7dc64e, | ||
799 | af9015_rc_keys_mygictv, ARRAY_SIZE(af9015_rc_keys_mygictv), | ||
800 | af9015_ir_table_mygictv, ARRAY_SIZE(af9015_ir_table_mygictv) }, | ||
801 | { } | ||
802 | }; | ||
803 | |||
804 | static void af9015_set_remote_config(struct usb_device *udev, | ||
805 | struct dvb_usb_device_properties *props) | ||
806 | { | ||
807 | const struct af9015_setup *table = NULL; | ||
808 | |||
809 | if (dvb_usb_af9015_remote) { | ||
810 | /* load remote defined as module param */ | ||
811 | table = af9015_setup_match(dvb_usb_af9015_remote, | ||
812 | af9015_setup_modparam); | ||
813 | } else { | ||
814 | u16 vendor = le16_to_cpu(udev->descriptor.idVendor); | ||
815 | |||
816 | table = af9015_setup_match(af9015_config.eeprom_sum, | ||
817 | af9015_setup_hashes); | ||
818 | |||
819 | if (!table && vendor == USB_VID_AFATECH) { | ||
820 | /* Check USB manufacturer and product strings and try | ||
821 | to determine correct remote in case of chip vendor | ||
822 | reference IDs are used. | ||
823 | DO NOT ADD ANYTHING NEW HERE. Use hashes instead. | ||
824 | */ | ||
825 | char manufacturer[10]; | ||
826 | memset(manufacturer, 0, sizeof(manufacturer)); | ||
827 | usb_string(udev, udev->descriptor.iManufacturer, | ||
828 | manufacturer, sizeof(manufacturer)); | ||
829 | if (!strcmp("MSI", manufacturer)) { | ||
830 | /* iManufacturer 1 MSI | ||
831 | iProduct 2 MSI K-VOX */ | ||
832 | table = af9015_setup_match( | ||
833 | AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, | ||
834 | af9015_setup_modparam); | ||
835 | } else if (udev->descriptor.idProduct == | ||
836 | cpu_to_le16(USB_PID_TREKSTOR_DVBT)) { | ||
837 | table = &(const struct af9015_setup){ 0, | ||
838 | af9015_rc_keys_trekstor, | ||
839 | ARRAY_SIZE(af9015_rc_keys_trekstor), | ||
840 | af9015_ir_table_trekstor, | ||
841 | ARRAY_SIZE(af9015_ir_table_trekstor) | ||
842 | }; | ||
843 | } | ||
844 | } else if (!table) | ||
845 | table = af9015_setup_match(vendor, af9015_setup_usbids); | ||
846 | } | ||
847 | |||
848 | if (table) { | ||
849 | props->rc_key_map = table->rc_key_map; | ||
850 | props->rc_key_map_size = table->rc_key_map_size; | ||
851 | af9015_config.ir_table = table->ir_table; | ||
852 | af9015_config.ir_table_size = table->ir_table_size; | ||
853 | } | ||
854 | } | ||
855 | |||
714 | static int af9015_read_config(struct usb_device *udev) | 856 | static int af9015_read_config(struct usb_device *udev) |
715 | { | 857 | { |
716 | int ret; | 858 | int ret; |
717 | u8 val, i, offset = 0; | 859 | u8 val, i, offset = 0; |
718 | struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val}; | 860 | struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val}; |
719 | char manufacturer[10]; | ||
720 | 861 | ||
721 | /* IR remote controller */ | 862 | /* IR remote controller */ |
722 | req.addr = AF9015_EEPROM_IR_MODE; | 863 | req.addr = AF9015_EEPROM_IR_MODE; |
@@ -728,158 +869,18 @@ static int af9015_read_config(struct usb_device *udev) | |||
728 | } | 869 | } |
729 | if (ret) | 870 | if (ret) |
730 | goto error; | 871 | goto error; |
872 | |||
873 | ret = af9015_eeprom_hash(udev); | ||
874 | if (ret) | ||
875 | goto error; | ||
876 | |||
731 | deb_info("%s: IR mode:%d\n", __func__, val); | 877 | deb_info("%s: IR mode:%d\n", __func__, val); |
732 | for (i = 0; i < af9015_properties_count; i++) { | 878 | for (i = 0; i < af9015_properties_count; i++) { |
733 | if (val == AF9015_IR_MODE_DISABLED) { | 879 | if (val == AF9015_IR_MODE_DISABLED) { |
734 | af9015_properties[i].rc_key_map = NULL; | 880 | af9015_properties[i].rc_key_map = NULL; |
735 | af9015_properties[i].rc_key_map_size = 0; | 881 | af9015_properties[i].rc_key_map_size = 0; |
736 | } else if (dvb_usb_af9015_remote) { | 882 | } else |
737 | /* load remote defined as module param */ | 883 | af9015_set_remote_config(udev, &af9015_properties[i]); |
738 | switch (dvb_usb_af9015_remote) { | ||
739 | case AF9015_REMOTE_A_LINK_DTU_M: | ||
740 | af9015_properties[i].rc_key_map = | ||
741 | af9015_rc_keys_a_link; | ||
742 | af9015_properties[i].rc_key_map_size = | ||
743 | ARRAY_SIZE(af9015_rc_keys_a_link); | ||
744 | af9015_config.ir_table = af9015_ir_table_a_link; | ||
745 | af9015_config.ir_table_size = | ||
746 | ARRAY_SIZE(af9015_ir_table_a_link); | ||
747 | break; | ||
748 | case AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3: | ||
749 | af9015_properties[i].rc_key_map = | ||
750 | af9015_rc_keys_msi; | ||
751 | af9015_properties[i].rc_key_map_size = | ||
752 | ARRAY_SIZE(af9015_rc_keys_msi); | ||
753 | af9015_config.ir_table = af9015_ir_table_msi; | ||
754 | af9015_config.ir_table_size = | ||
755 | ARRAY_SIZE(af9015_ir_table_msi); | ||
756 | break; | ||
757 | case AF9015_REMOTE_MYGICTV_U718: | ||
758 | af9015_properties[i].rc_key_map = | ||
759 | af9015_rc_keys_mygictv; | ||
760 | af9015_properties[i].rc_key_map_size = | ||
761 | ARRAY_SIZE(af9015_rc_keys_mygictv); | ||
762 | af9015_config.ir_table = | ||
763 | af9015_ir_table_mygictv; | ||
764 | af9015_config.ir_table_size = | ||
765 | ARRAY_SIZE(af9015_ir_table_mygictv); | ||
766 | break; | ||
767 | case AF9015_REMOTE_DIGITTRADE_DVB_T: | ||
768 | af9015_properties[i].rc_key_map = | ||
769 | af9015_rc_keys_digittrade; | ||
770 | af9015_properties[i].rc_key_map_size = | ||
771 | ARRAY_SIZE(af9015_rc_keys_digittrade); | ||
772 | af9015_config.ir_table = | ||
773 | af9015_ir_table_digittrade; | ||
774 | af9015_config.ir_table_size = | ||
775 | ARRAY_SIZE(af9015_ir_table_digittrade); | ||
776 | break; | ||
777 | case AF9015_REMOTE_AVERMEDIA_KS: | ||
778 | af9015_properties[i].rc_key_map = | ||
779 | af9015_rc_keys_avermedia; | ||
780 | af9015_properties[i].rc_key_map_size = | ||
781 | ARRAY_SIZE(af9015_rc_keys_avermedia); | ||
782 | af9015_config.ir_table = | ||
783 | af9015_ir_table_avermedia_ks; | ||
784 | af9015_config.ir_table_size = | ||
785 | ARRAY_SIZE(af9015_ir_table_avermedia_ks); | ||
786 | break; | ||
787 | } | ||
788 | } else { | ||
789 | switch (le16_to_cpu(udev->descriptor.idVendor)) { | ||
790 | case USB_VID_LEADTEK: | ||
791 | af9015_properties[i].rc_key_map = | ||
792 | af9015_rc_keys_leadtek; | ||
793 | af9015_properties[i].rc_key_map_size = | ||
794 | ARRAY_SIZE(af9015_rc_keys_leadtek); | ||
795 | af9015_config.ir_table = | ||
796 | af9015_ir_table_leadtek; | ||
797 | af9015_config.ir_table_size = | ||
798 | ARRAY_SIZE(af9015_ir_table_leadtek); | ||
799 | break; | ||
800 | case USB_VID_VISIONPLUS: | ||
801 | af9015_properties[i].rc_key_map = | ||
802 | af9015_rc_keys_twinhan; | ||
803 | af9015_properties[i].rc_key_map_size = | ||
804 | ARRAY_SIZE(af9015_rc_keys_twinhan); | ||
805 | af9015_config.ir_table = | ||
806 | af9015_ir_table_twinhan; | ||
807 | af9015_config.ir_table_size = | ||
808 | ARRAY_SIZE(af9015_ir_table_twinhan); | ||
809 | break; | ||
810 | case USB_VID_KWORLD_2: | ||
811 | /* TODO: use correct rc keys */ | ||
812 | af9015_properties[i].rc_key_map = | ||
813 | af9015_rc_keys_twinhan; | ||
814 | af9015_properties[i].rc_key_map_size = | ||
815 | ARRAY_SIZE(af9015_rc_keys_twinhan); | ||
816 | af9015_config.ir_table = af9015_ir_table_kworld; | ||
817 | af9015_config.ir_table_size = | ||
818 | ARRAY_SIZE(af9015_ir_table_kworld); | ||
819 | break; | ||
820 | /* Check USB manufacturer and product strings and try | ||
821 | to determine correct remote in case of chip vendor | ||
822 | reference IDs are used. */ | ||
823 | case USB_VID_AFATECH: | ||
824 | memset(manufacturer, 0, sizeof(manufacturer)); | ||
825 | usb_string(udev, udev->descriptor.iManufacturer, | ||
826 | manufacturer, sizeof(manufacturer)); | ||
827 | if (!strcmp("Geniatech", manufacturer)) { | ||
828 | /* iManufacturer 1 Geniatech | ||
829 | iProduct 2 AF9015 */ | ||
830 | af9015_properties[i].rc_key_map = | ||
831 | af9015_rc_keys_mygictv; | ||
832 | af9015_properties[i].rc_key_map_size = | ||
833 | ARRAY_SIZE(af9015_rc_keys_mygictv); | ||
834 | af9015_config.ir_table = | ||
835 | af9015_ir_table_mygictv; | ||
836 | af9015_config.ir_table_size = | ||
837 | ARRAY_SIZE(af9015_ir_table_mygictv); | ||
838 | } else if (!strcmp("MSI", manufacturer)) { | ||
839 | /* iManufacturer 1 MSI | ||
840 | iProduct 2 MSI K-VOX */ | ||
841 | af9015_properties[i].rc_key_map = | ||
842 | af9015_rc_keys_msi; | ||
843 | af9015_properties[i].rc_key_map_size = | ||
844 | ARRAY_SIZE(af9015_rc_keys_msi); | ||
845 | af9015_config.ir_table = | ||
846 | af9015_ir_table_msi; | ||
847 | af9015_config.ir_table_size = | ||
848 | ARRAY_SIZE(af9015_ir_table_msi); | ||
849 | } else if (udev->descriptor.idProduct == | ||
850 | cpu_to_le16(USB_PID_TREKSTOR_DVBT)) { | ||
851 | af9015_properties[i].rc_key_map = | ||
852 | af9015_rc_keys_trekstor; | ||
853 | af9015_properties[i].rc_key_map_size = | ||
854 | ARRAY_SIZE(af9015_rc_keys_trekstor); | ||
855 | af9015_config.ir_table = | ||
856 | af9015_ir_table_trekstor; | ||
857 | af9015_config.ir_table_size = | ||
858 | ARRAY_SIZE(af9015_ir_table_trekstor); | ||
859 | } | ||
860 | break; | ||
861 | case USB_VID_AVERMEDIA: | ||
862 | af9015_properties[i].rc_key_map = | ||
863 | af9015_rc_keys_avermedia; | ||
864 | af9015_properties[i].rc_key_map_size = | ||
865 | ARRAY_SIZE(af9015_rc_keys_avermedia); | ||
866 | af9015_config.ir_table = | ||
867 | af9015_ir_table_avermedia; | ||
868 | af9015_config.ir_table_size = | ||
869 | ARRAY_SIZE(af9015_ir_table_avermedia); | ||
870 | break; | ||
871 | case USB_VID_MSI_2: | ||
872 | af9015_properties[i].rc_key_map = | ||
873 | af9015_rc_keys_msi_digivox_iii; | ||
874 | af9015_properties[i].rc_key_map_size = | ||
875 | ARRAY_SIZE(af9015_rc_keys_msi_digivox_iii); | ||
876 | af9015_config.ir_table = | ||
877 | af9015_ir_table_msi_digivox_iii; | ||
878 | af9015_config.ir_table_size = | ||
879 | ARRAY_SIZE(af9015_ir_table_msi_digivox_iii); | ||
880 | break; | ||
881 | } | ||
882 | } | ||
883 | } | 884 | } |
884 | 885 | ||
885 | /* TS mode - one or two receivers */ | 886 | /* TS mode - one or two receivers */ |
@@ -1001,6 +1002,9 @@ static int af9015_read_config(struct usb_device *udev) | |||
1001 | af9015_af9013_config[i].gpio[1] = AF9013_GPIO_LO; | 1002 | af9015_af9013_config[i].gpio[1] = AF9013_GPIO_LO; |
1002 | af9015_af9013_config[i].rf_spec_inv = 1; | 1003 | af9015_af9013_config[i].rf_spec_inv = 1; |
1003 | break; | 1004 | break; |
1005 | case AF9013_TUNER_TDA18218: | ||
1006 | warn("tuner NXP TDA18218 not supported yet"); | ||
1007 | return -ENODEV; | ||
1004 | default: | 1008 | default: |
1005 | warn("tuner id:%d not supported, please report!", val); | 1009 | warn("tuner id:%d not supported, please report!", val); |
1006 | return -ENODEV; | 1010 | return -ENODEV; |
@@ -1125,11 +1129,6 @@ static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap) | |||
1125 | 1129 | ||
1126 | deb_info("%s: init I2C\n", __func__); | 1130 | deb_info("%s: init I2C\n", __func__); |
1127 | ret = af9015_i2c_init(adap->dev); | 1131 | ret = af9015_i2c_init(adap->dev); |
1128 | |||
1129 | /* dump eeprom (debug) */ | ||
1130 | ret = af9015_eeprom_dump(adap->dev); | ||
1131 | if (ret) | ||
1132 | return ret; | ||
1133 | } else { | 1132 | } else { |
1134 | /* select I2C adapter */ | 1133 | /* select I2C adapter */ |
1135 | i2c_adap = &state->i2c_adap; | 1134 | i2c_adap = &state->i2c_adap; |
@@ -1295,6 +1294,8 @@ static struct usb_device_id af9015_usb_table[] = { | |||
1295 | /* 25 */{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U_2)}, | 1294 | /* 25 */{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U_2)}, |
1296 | {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_T)}, | 1295 | {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_T)}, |
1297 | {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV20)}, | 1296 | {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV20)}, |
1297 | {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_TINYTWIN_2)}, | ||
1298 | {USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV2000DS)}, | ||
1298 | {0}, | 1299 | {0}, |
1299 | }; | 1300 | }; |
1300 | MODULE_DEVICE_TABLE(usb, af9015_usb_table); | 1301 | MODULE_DEVICE_TABLE(usb, af9015_usb_table); |
@@ -1381,7 +1382,8 @@ static struct dvb_usb_device_properties af9015_properties[] = { | |||
1381 | }, | 1382 | }, |
1382 | { | 1383 | { |
1383 | .name = "DigitalNow TinyTwin DVB-T Receiver", | 1384 | .name = "DigitalNow TinyTwin DVB-T Receiver", |
1384 | .cold_ids = {&af9015_usb_table[5], NULL}, | 1385 | .cold_ids = {&af9015_usb_table[5], |
1386 | &af9015_usb_table[28], NULL}, | ||
1385 | .warm_ids = {NULL}, | 1387 | .warm_ids = {NULL}, |
1386 | }, | 1388 | }, |
1387 | { | 1389 | { |
@@ -1566,7 +1568,7 @@ static struct dvb_usb_device_properties af9015_properties[] = { | |||
1566 | 1568 | ||
1567 | .i2c_algo = &af9015_i2c_algo, | 1569 | .i2c_algo = &af9015_i2c_algo, |
1568 | 1570 | ||
1569 | .num_device_descs = 6, /* max 9 */ | 1571 | .num_device_descs = 7, /* max 9 */ |
1570 | .devices = { | 1572 | .devices = { |
1571 | { | 1573 | { |
1572 | .name = "AverMedia AVerTV Volar GPS 805 (A805)", | 1574 | .name = "AverMedia AVerTV Volar GPS 805 (A805)", |
@@ -1600,6 +1602,11 @@ static struct dvb_usb_device_properties af9015_properties[] = { | |||
1600 | .cold_ids = {&af9015_usb_table[27], NULL}, | 1602 | .cold_ids = {&af9015_usb_table[27], NULL}, |
1601 | .warm_ids = {NULL}, | 1603 | .warm_ids = {NULL}, |
1602 | }, | 1604 | }, |
1605 | { | ||
1606 | .name = "Leadtek WinFast DTV2000DS", | ||
1607 | .cold_ids = {&af9015_usb_table[29], NULL}, | ||
1608 | .warm_ids = {NULL}, | ||
1609 | }, | ||
1603 | } | 1610 | } |
1604 | }, | 1611 | }, |
1605 | }; | 1612 | }; |
diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h index 931c8515830d..ef36b1831490 100644 --- a/drivers/media/dvb/dvb-usb/af9015.h +++ b/drivers/media/dvb/dvb-usb/af9015.h | |||
@@ -107,6 +107,7 @@ struct af9015_config { | |||
107 | u16 mt2060_if1[2]; | 107 | u16 mt2060_if1[2]; |
108 | u16 firmware_size; | 108 | u16 firmware_size; |
109 | u16 firmware_checksum; | 109 | u16 firmware_checksum; |
110 | u32 eeprom_sum; | ||
110 | u8 *ir_table; | 111 | u8 *ir_table; |
111 | u16 ir_table_size; | 112 | u16 ir_table_size; |
112 | }; | 113 | }; |
diff --git a/drivers/media/dvb/dvb-usb/az6027.c b/drivers/media/dvb/dvb-usb/az6027.c new file mode 100644 index 000000000000..d7290b2c0913 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/az6027.c | |||
@@ -0,0 +1,1151 @@ | |||
1 | /* DVB USB compliant Linux driver for the AZUREWAVE DVB-S/S2 USB2.0 (AZ6027) | ||
2 | * receiver. | ||
3 | * | ||
4 | * Copyright (C) 2009 Adams.Xu <adams.xu@azwave.com.cn> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the Free | ||
8 | * Software Foundation, version 2. | ||
9 | * | ||
10 | * see Documentation/dvb/README.dvb-usb for more information | ||
11 | */ | ||
12 | #include "az6027.h" | ||
13 | |||
14 | #include "stb0899_drv.h" | ||
15 | #include "stb0899_reg.h" | ||
16 | #include "stb0899_cfg.h" | ||
17 | |||
18 | #include "stb6100.h" | ||
19 | #include "stb6100_cfg.h" | ||
20 | #include "dvb_ca_en50221.h" | ||
21 | |||
22 | int dvb_usb_az6027_debug; | ||
23 | module_param_named(debug, dvb_usb_az6027_debug, int, 0644); | ||
24 | MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS); | ||
25 | |||
26 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
27 | |||
28 | struct az6027_device_state { | ||
29 | struct dvb_ca_en50221 ca; | ||
30 | struct mutex ca_mutex; | ||
31 | u8 power_state; | ||
32 | }; | ||
33 | |||
34 | static const struct stb0899_s1_reg az6027_stb0899_s1_init_1[] = { | ||
35 | |||
36 | /* 0x0000000b, SYSREG */ | ||
37 | { STB0899_DEV_ID , 0x30 }, | ||
38 | { STB0899_DISCNTRL1 , 0x32 }, | ||
39 | { STB0899_DISCNTRL2 , 0x80 }, | ||
40 | { STB0899_DISRX_ST0 , 0x04 }, | ||
41 | { STB0899_DISRX_ST1 , 0x00 }, | ||
42 | { STB0899_DISPARITY , 0x00 }, | ||
43 | { STB0899_DISFIFO , 0x00 }, | ||
44 | { STB0899_DISSTATUS , 0x20 }, | ||
45 | { STB0899_DISF22 , 0x99 }, | ||
46 | { STB0899_DISF22RX , 0xa8 }, | ||
47 | /* SYSREG ? */ | ||
48 | { STB0899_ACRPRESC , 0x11 }, | ||
49 | { STB0899_ACRDIV1 , 0x0a }, | ||
50 | { STB0899_ACRDIV2 , 0x05 }, | ||
51 | { STB0899_DACR1 , 0x00 }, | ||
52 | { STB0899_DACR2 , 0x00 }, | ||
53 | { STB0899_OUTCFG , 0x00 }, | ||
54 | { STB0899_MODECFG , 0x00 }, | ||
55 | { STB0899_IRQSTATUS_3 , 0xfe }, | ||
56 | { STB0899_IRQSTATUS_2 , 0x03 }, | ||
57 | { STB0899_IRQSTATUS_1 , 0x7c }, | ||
58 | { STB0899_IRQSTATUS_0 , 0xf4 }, | ||
59 | { STB0899_IRQMSK_3 , 0xf3 }, | ||
60 | { STB0899_IRQMSK_2 , 0xfc }, | ||
61 | { STB0899_IRQMSK_1 , 0xff }, | ||
62 | { STB0899_IRQMSK_0 , 0xff }, | ||
63 | { STB0899_IRQCFG , 0x00 }, | ||
64 | { STB0899_I2CCFG , 0x88 }, | ||
65 | { STB0899_I2CRPT , 0x58 }, | ||
66 | { STB0899_IOPVALUE5 , 0x00 }, | ||
67 | { STB0899_IOPVALUE4 , 0x33 }, | ||
68 | { STB0899_IOPVALUE3 , 0x6d }, | ||
69 | { STB0899_IOPVALUE2 , 0x90 }, | ||
70 | { STB0899_IOPVALUE1 , 0x60 }, | ||
71 | { STB0899_IOPVALUE0 , 0x00 }, | ||
72 | { STB0899_GPIO00CFG , 0x82 }, | ||
73 | { STB0899_GPIO01CFG , 0x82 }, | ||
74 | { STB0899_GPIO02CFG , 0x82 }, | ||
75 | { STB0899_GPIO03CFG , 0x82 }, | ||
76 | { STB0899_GPIO04CFG , 0x82 }, | ||
77 | { STB0899_GPIO05CFG , 0x82 }, | ||
78 | { STB0899_GPIO06CFG , 0x82 }, | ||
79 | { STB0899_GPIO07CFG , 0x82 }, | ||
80 | { STB0899_GPIO08CFG , 0x82 }, | ||
81 | { STB0899_GPIO09CFG , 0x82 }, | ||
82 | { STB0899_GPIO10CFG , 0x82 }, | ||
83 | { STB0899_GPIO11CFG , 0x82 }, | ||
84 | { STB0899_GPIO12CFG , 0x82 }, | ||
85 | { STB0899_GPIO13CFG , 0x82 }, | ||
86 | { STB0899_GPIO14CFG , 0x82 }, | ||
87 | { STB0899_GPIO15CFG , 0x82 }, | ||
88 | { STB0899_GPIO16CFG , 0x82 }, | ||
89 | { STB0899_GPIO17CFG , 0x82 }, | ||
90 | { STB0899_GPIO18CFG , 0x82 }, | ||
91 | { STB0899_GPIO19CFG , 0x82 }, | ||
92 | { STB0899_GPIO20CFG , 0x82 }, | ||
93 | { STB0899_SDATCFG , 0xb8 }, | ||
94 | { STB0899_SCLTCFG , 0xba }, | ||
95 | { STB0899_AGCRFCFG , 0x1c }, /* 0x11 */ | ||
96 | { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */ | ||
97 | { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */ | ||
98 | { STB0899_DIRCLKCFG , 0x82 }, | ||
99 | { STB0899_CLKOUT27CFG , 0x7e }, | ||
100 | { STB0899_STDBYCFG , 0x82 }, | ||
101 | { STB0899_CS0CFG , 0x82 }, | ||
102 | { STB0899_CS1CFG , 0x82 }, | ||
103 | { STB0899_DISEQCOCFG , 0x20 }, | ||
104 | { STB0899_GPIO32CFG , 0x82 }, | ||
105 | { STB0899_GPIO33CFG , 0x82 }, | ||
106 | { STB0899_GPIO34CFG , 0x82 }, | ||
107 | { STB0899_GPIO35CFG , 0x82 }, | ||
108 | { STB0899_GPIO36CFG , 0x82 }, | ||
109 | { STB0899_GPIO37CFG , 0x82 }, | ||
110 | { STB0899_GPIO38CFG , 0x82 }, | ||
111 | { STB0899_GPIO39CFG , 0x82 }, | ||
112 | { STB0899_NCOARSE , 0x17 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */ | ||
113 | { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */ | ||
114 | { STB0899_FILTCTRL , 0x00 }, | ||
115 | { STB0899_SYSCTRL , 0x01 }, | ||
116 | { STB0899_STOPCLK1 , 0x20 }, | ||
117 | { STB0899_STOPCLK2 , 0x00 }, | ||
118 | { STB0899_INTBUFSTATUS , 0x00 }, | ||
119 | { STB0899_INTBUFCTRL , 0x0a }, | ||
120 | { 0xffff , 0xff }, | ||
121 | }; | ||
122 | |||
123 | static const struct stb0899_s1_reg az6027_stb0899_s1_init_3[] = { | ||
124 | { STB0899_DEMOD , 0x00 }, | ||
125 | { STB0899_RCOMPC , 0xc9 }, | ||
126 | { STB0899_AGC1CN , 0x01 }, | ||
127 | { STB0899_AGC1REF , 0x10 }, | ||
128 | { STB0899_RTC , 0x23 }, | ||
129 | { STB0899_TMGCFG , 0x4e }, | ||
130 | { STB0899_AGC2REF , 0x34 }, | ||
131 | { STB0899_TLSR , 0x84 }, | ||
132 | { STB0899_CFD , 0xf7 }, | ||
133 | { STB0899_ACLC , 0x87 }, | ||
134 | { STB0899_BCLC , 0x94 }, | ||
135 | { STB0899_EQON , 0x41 }, | ||
136 | { STB0899_LDT , 0xf1 }, | ||
137 | { STB0899_LDT2 , 0xe3 }, | ||
138 | { STB0899_EQUALREF , 0xb4 }, | ||
139 | { STB0899_TMGRAMP , 0x10 }, | ||
140 | { STB0899_TMGTHD , 0x30 }, | ||
141 | { STB0899_IDCCOMP , 0xfd }, | ||
142 | { STB0899_QDCCOMP , 0xff }, | ||
143 | { STB0899_POWERI , 0x0c }, | ||
144 | { STB0899_POWERQ , 0x0f }, | ||
145 | { STB0899_RCOMP , 0x6c }, | ||
146 | { STB0899_AGCIQIN , 0x80 }, | ||
147 | { STB0899_AGC2I1 , 0x06 }, | ||
148 | { STB0899_AGC2I2 , 0x00 }, | ||
149 | { STB0899_TLIR , 0x30 }, | ||
150 | { STB0899_RTF , 0x7f }, | ||
151 | { STB0899_DSTATUS , 0x00 }, | ||
152 | { STB0899_LDI , 0xbc }, | ||
153 | { STB0899_CFRM , 0xea }, | ||
154 | { STB0899_CFRL , 0x31 }, | ||
155 | { STB0899_NIRM , 0x2b }, | ||
156 | { STB0899_NIRL , 0x80 }, | ||
157 | { STB0899_ISYMB , 0x1d }, | ||
158 | { STB0899_QSYMB , 0xa6 }, | ||
159 | { STB0899_SFRH , 0x2f }, | ||
160 | { STB0899_SFRM , 0x68 }, | ||
161 | { STB0899_SFRL , 0x40 }, | ||
162 | { STB0899_SFRUPH , 0x2f }, | ||
163 | { STB0899_SFRUPM , 0x68 }, | ||
164 | { STB0899_SFRUPL , 0x40 }, | ||
165 | { STB0899_EQUAI1 , 0x02 }, | ||
166 | { STB0899_EQUAQ1 , 0xff }, | ||
167 | { STB0899_EQUAI2 , 0x04 }, | ||
168 | { STB0899_EQUAQ2 , 0x05 }, | ||
169 | { STB0899_EQUAI3 , 0x02 }, | ||
170 | { STB0899_EQUAQ3 , 0xfd }, | ||
171 | { STB0899_EQUAI4 , 0x03 }, | ||
172 | { STB0899_EQUAQ4 , 0x07 }, | ||
173 | { STB0899_EQUAI5 , 0x08 }, | ||
174 | { STB0899_EQUAQ5 , 0xf5 }, | ||
175 | { STB0899_DSTATUS2 , 0x00 }, | ||
176 | { STB0899_VSTATUS , 0x00 }, | ||
177 | { STB0899_VERROR , 0x86 }, | ||
178 | { STB0899_IQSWAP , 0x2a }, | ||
179 | { STB0899_ECNT1M , 0x00 }, | ||
180 | { STB0899_ECNT1L , 0x00 }, | ||
181 | { STB0899_ECNT2M , 0x00 }, | ||
182 | { STB0899_ECNT2L , 0x00 }, | ||
183 | { STB0899_ECNT3M , 0x0a }, | ||
184 | { STB0899_ECNT3L , 0xad }, | ||
185 | { STB0899_FECAUTO1 , 0x06 }, | ||
186 | { STB0899_FECM , 0x01 }, | ||
187 | { STB0899_VTH12 , 0xb0 }, | ||
188 | { STB0899_VTH23 , 0x7a }, | ||
189 | { STB0899_VTH34 , 0x58 }, | ||
190 | { STB0899_VTH56 , 0x38 }, | ||
191 | { STB0899_VTH67 , 0x34 }, | ||
192 | { STB0899_VTH78 , 0x24 }, | ||
193 | { STB0899_PRVIT , 0xff }, | ||
194 | { STB0899_VITSYNC , 0x19 }, | ||
195 | { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */ | ||
196 | { STB0899_TSULC , 0x42 }, | ||
197 | { STB0899_RSLLC , 0x41 }, | ||
198 | { STB0899_TSLPL , 0x12 }, | ||
199 | { STB0899_TSCFGH , 0x0c }, | ||
200 | { STB0899_TSCFGM , 0x00 }, | ||
201 | { STB0899_TSCFGL , 0x00 }, | ||
202 | { STB0899_TSOUT , 0x69 }, /* 0x0d for CAM */ | ||
203 | { STB0899_RSSYNCDEL , 0x00 }, | ||
204 | { STB0899_TSINHDELH , 0x02 }, | ||
205 | { STB0899_TSINHDELM , 0x00 }, | ||
206 | { STB0899_TSINHDELL , 0x00 }, | ||
207 | { STB0899_TSLLSTKM , 0x1b }, | ||
208 | { STB0899_TSLLSTKL , 0xb3 }, | ||
209 | { STB0899_TSULSTKM , 0x00 }, | ||
210 | { STB0899_TSULSTKL , 0x00 }, | ||
211 | { STB0899_PCKLENUL , 0xbc }, | ||
212 | { STB0899_PCKLENLL , 0xcc }, | ||
213 | { STB0899_RSPCKLEN , 0xbd }, | ||
214 | { STB0899_TSSTATUS , 0x90 }, | ||
215 | { STB0899_ERRCTRL1 , 0xb6 }, | ||
216 | { STB0899_ERRCTRL2 , 0x95 }, | ||
217 | { STB0899_ERRCTRL3 , 0x8d }, | ||
218 | { STB0899_DMONMSK1 , 0x27 }, | ||
219 | { STB0899_DMONMSK0 , 0x03 }, | ||
220 | { STB0899_DEMAPVIT , 0x5c }, | ||
221 | { STB0899_PLPARM , 0x19 }, | ||
222 | { STB0899_PDELCTRL , 0x48 }, | ||
223 | { STB0899_PDELCTRL2 , 0x00 }, | ||
224 | { STB0899_BBHCTRL1 , 0x00 }, | ||
225 | { STB0899_BBHCTRL2 , 0x00 }, | ||
226 | { STB0899_HYSTTHRESH , 0x77 }, | ||
227 | { STB0899_MATCSTM , 0x00 }, | ||
228 | { STB0899_MATCSTL , 0x00 }, | ||
229 | { STB0899_UPLCSTM , 0x00 }, | ||
230 | { STB0899_UPLCSTL , 0x00 }, | ||
231 | { STB0899_DFLCSTM , 0x00 }, | ||
232 | { STB0899_DFLCSTL , 0x00 }, | ||
233 | { STB0899_SYNCCST , 0x00 }, | ||
234 | { STB0899_SYNCDCSTM , 0x00 }, | ||
235 | { STB0899_SYNCDCSTL , 0x00 }, | ||
236 | { STB0899_ISI_ENTRY , 0x00 }, | ||
237 | { STB0899_ISI_BIT_EN , 0x00 }, | ||
238 | { STB0899_MATSTRM , 0xf0 }, | ||
239 | { STB0899_MATSTRL , 0x02 }, | ||
240 | { STB0899_UPLSTRM , 0x45 }, | ||
241 | { STB0899_UPLSTRL , 0x60 }, | ||
242 | { STB0899_DFLSTRM , 0xe3 }, | ||
243 | { STB0899_DFLSTRL , 0x00 }, | ||
244 | { STB0899_SYNCSTR , 0x47 }, | ||
245 | { STB0899_SYNCDSTRM , 0x05 }, | ||
246 | { STB0899_SYNCDSTRL , 0x18 }, | ||
247 | { STB0899_CFGPDELSTATUS1 , 0x19 }, | ||
248 | { STB0899_CFGPDELSTATUS2 , 0x2b }, | ||
249 | { STB0899_BBFERRORM , 0x00 }, | ||
250 | { STB0899_BBFERRORL , 0x01 }, | ||
251 | { STB0899_UPKTERRORM , 0x00 }, | ||
252 | { STB0899_UPKTERRORL , 0x00 }, | ||
253 | { 0xffff , 0xff }, | ||
254 | }; | ||
255 | |||
256 | |||
257 | |||
258 | struct stb0899_config az6027_stb0899_config = { | ||
259 | .init_dev = az6027_stb0899_s1_init_1, | ||
260 | .init_s2_demod = stb0899_s2_init_2, | ||
261 | .init_s1_demod = az6027_stb0899_s1_init_3, | ||
262 | .init_s2_fec = stb0899_s2_init_4, | ||
263 | .init_tst = stb0899_s1_init_5, | ||
264 | |||
265 | .demod_address = 0xd0, /* 0x68, 0xd0 >> 1 */ | ||
266 | |||
267 | .xtal_freq = 27000000, | ||
268 | .inversion = IQ_SWAP_ON, /* 1 */ | ||
269 | |||
270 | .lo_clk = 76500000, | ||
271 | .hi_clk = 99000000, | ||
272 | |||
273 | .esno_ave = STB0899_DVBS2_ESNO_AVE, | ||
274 | .esno_quant = STB0899_DVBS2_ESNO_QUANT, | ||
275 | .avframes_coarse = STB0899_DVBS2_AVFRAMES_COARSE, | ||
276 | .avframes_fine = STB0899_DVBS2_AVFRAMES_FINE, | ||
277 | .miss_threshold = STB0899_DVBS2_MISS_THRESHOLD, | ||
278 | .uwp_threshold_acq = STB0899_DVBS2_UWP_THRESHOLD_ACQ, | ||
279 | .uwp_threshold_track = STB0899_DVBS2_UWP_THRESHOLD_TRACK, | ||
280 | .uwp_threshold_sof = STB0899_DVBS2_UWP_THRESHOLD_SOF, | ||
281 | .sof_search_timeout = STB0899_DVBS2_SOF_SEARCH_TIMEOUT, | ||
282 | |||
283 | .btr_nco_bits = STB0899_DVBS2_BTR_NCO_BITS, | ||
284 | .btr_gain_shift_offset = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET, | ||
285 | .crl_nco_bits = STB0899_DVBS2_CRL_NCO_BITS, | ||
286 | .ldpc_max_iter = STB0899_DVBS2_LDPC_MAX_ITER, | ||
287 | |||
288 | .tuner_get_frequency = stb6100_get_frequency, | ||
289 | .tuner_set_frequency = stb6100_set_frequency, | ||
290 | .tuner_set_bandwidth = stb6100_set_bandwidth, | ||
291 | .tuner_get_bandwidth = stb6100_get_bandwidth, | ||
292 | .tuner_set_rfsiggain = NULL, | ||
293 | }; | ||
294 | |||
295 | struct stb6100_config az6027_stb6100_config = { | ||
296 | .tuner_address = 0xc0, | ||
297 | .refclock = 27000000, | ||
298 | }; | ||
299 | |||
300 | |||
301 | /* check for mutex FIXME */ | ||
302 | int az6027_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen) | ||
303 | { | ||
304 | int ret = -1; | ||
305 | if (mutex_lock_interruptible(&d->usb_mutex)) | ||
306 | return -EAGAIN; | ||
307 | |||
308 | ret = usb_control_msg(d->udev, | ||
309 | usb_rcvctrlpipe(d->udev, 0), | ||
310 | req, | ||
311 | USB_TYPE_VENDOR | USB_DIR_IN, | ||
312 | value, | ||
313 | index, | ||
314 | b, | ||
315 | blen, | ||
316 | 2000); | ||
317 | |||
318 | if (ret < 0) { | ||
319 | warn("usb in operation failed. (%d)", ret); | ||
320 | ret = -EIO; | ||
321 | } else | ||
322 | ret = 0; | ||
323 | |||
324 | deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ", req, value, index); | ||
325 | debug_dump(b, blen, deb_xfer); | ||
326 | |||
327 | mutex_unlock(&d->usb_mutex); | ||
328 | return ret; | ||
329 | } | ||
330 | |||
331 | static int az6027_usb_out_op(struct dvb_usb_device *d, | ||
332 | u8 req, | ||
333 | u16 value, | ||
334 | u16 index, | ||
335 | u8 *b, | ||
336 | int blen) | ||
337 | { | ||
338 | int ret; | ||
339 | |||
340 | deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ", req, value, index); | ||
341 | debug_dump(b, blen, deb_xfer); | ||
342 | |||
343 | if (mutex_lock_interruptible(&d->usb_mutex)) | ||
344 | return -EAGAIN; | ||
345 | |||
346 | ret = usb_control_msg(d->udev, | ||
347 | usb_sndctrlpipe(d->udev, 0), | ||
348 | req, | ||
349 | USB_TYPE_VENDOR | USB_DIR_OUT, | ||
350 | value, | ||
351 | index, | ||
352 | b, | ||
353 | blen, | ||
354 | 2000); | ||
355 | |||
356 | if (ret != blen) { | ||
357 | warn("usb out operation failed. (%d)", ret); | ||
358 | mutex_unlock(&d->usb_mutex); | ||
359 | return -EIO; | ||
360 | } else{ | ||
361 | mutex_unlock(&d->usb_mutex); | ||
362 | return 0; | ||
363 | } | ||
364 | } | ||
365 | |||
366 | static int az6027_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) | ||
367 | { | ||
368 | int ret; | ||
369 | u8 req; | ||
370 | u16 value; | ||
371 | u16 index; | ||
372 | int blen; | ||
373 | |||
374 | deb_info("%s %d", __func__, onoff); | ||
375 | |||
376 | req = 0xBC; | ||
377 | value = onoff; | ||
378 | index = 0; | ||
379 | blen = 0; | ||
380 | |||
381 | ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen); | ||
382 | if (ret != 0) | ||
383 | warn("usb out operation failed. (%d)", ret); | ||
384 | |||
385 | return ret; | ||
386 | } | ||
387 | |||
388 | /* keys for the enclosed remote control */ | ||
389 | static struct dvb_usb_rc_key az6027_rc_keys[] = { | ||
390 | { 0x01, KEY_1 }, | ||
391 | { 0x02, KEY_2 }, | ||
392 | }; | ||
393 | |||
394 | /* remote control stuff (does not work with my box) */ | ||
395 | static int az6027_rc_query(struct dvb_usb_device *d, u32 *event, int *state) | ||
396 | { | ||
397 | return 0; | ||
398 | } | ||
399 | |||
400 | /* | ||
401 | int az6027_power_ctrl(struct dvb_usb_device *d, int onoff) | ||
402 | { | ||
403 | u8 v = onoff; | ||
404 | return az6027_usb_out_op(d,0xBC,v,3,NULL,1); | ||
405 | } | ||
406 | */ | ||
407 | |||
408 | static int az6027_ci_read_attribute_mem(struct dvb_ca_en50221 *ca, | ||
409 | int slot, | ||
410 | int address) | ||
411 | { | ||
412 | struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; | ||
413 | struct az6027_device_state *state = (struct az6027_device_state *)d->priv; | ||
414 | |||
415 | int ret; | ||
416 | u8 req; | ||
417 | u16 value; | ||
418 | u16 index; | ||
419 | int blen; | ||
420 | u8 b[12]; | ||
421 | |||
422 | if (slot != 0) | ||
423 | return -EINVAL; | ||
424 | |||
425 | mutex_lock(&state->ca_mutex); | ||
426 | |||
427 | req = 0xC1; | ||
428 | value = address; | ||
429 | index = 0; | ||
430 | blen = 1; | ||
431 | |||
432 | ret = az6027_usb_in_op(d, req, value, index, b, blen); | ||
433 | if (ret < 0) { | ||
434 | warn("usb in operation failed. (%d)", ret); | ||
435 | ret = -EINVAL; | ||
436 | } else { | ||
437 | ret = b[0]; | ||
438 | } | ||
439 | |||
440 | mutex_unlock(&state->ca_mutex); | ||
441 | return ret; | ||
442 | } | ||
443 | |||
444 | static int az6027_ci_write_attribute_mem(struct dvb_ca_en50221 *ca, | ||
445 | int slot, | ||
446 | int address, | ||
447 | u8 value) | ||
448 | { | ||
449 | struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; | ||
450 | struct az6027_device_state *state = (struct az6027_device_state *)d->priv; | ||
451 | |||
452 | int ret; | ||
453 | u8 req; | ||
454 | u16 value1; | ||
455 | u16 index; | ||
456 | int blen; | ||
457 | |||
458 | deb_info("%s %d", __func__, slot); | ||
459 | if (slot != 0) | ||
460 | return -EINVAL; | ||
461 | |||
462 | mutex_lock(&state->ca_mutex); | ||
463 | req = 0xC2; | ||
464 | value1 = address; | ||
465 | index = value; | ||
466 | blen = 0; | ||
467 | |||
468 | ret = az6027_usb_out_op(d, req, value1, index, NULL, blen); | ||
469 | if (ret != 0) | ||
470 | warn("usb out operation failed. (%d)", ret); | ||
471 | |||
472 | mutex_unlock(&state->ca_mutex); | ||
473 | return ret; | ||
474 | } | ||
475 | |||
476 | static int az6027_ci_read_cam_control(struct dvb_ca_en50221 *ca, | ||
477 | int slot, | ||
478 | u8 address) | ||
479 | { | ||
480 | struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; | ||
481 | struct az6027_device_state *state = (struct az6027_device_state *)d->priv; | ||
482 | |||
483 | int ret; | ||
484 | u8 req; | ||
485 | u16 value; | ||
486 | u16 index; | ||
487 | int blen; | ||
488 | u8 b[12]; | ||
489 | |||
490 | if (slot != 0) | ||
491 | return -EINVAL; | ||
492 | |||
493 | mutex_lock(&state->ca_mutex); | ||
494 | |||
495 | req = 0xC3; | ||
496 | value = address; | ||
497 | index = 0; | ||
498 | blen = 2; | ||
499 | |||
500 | ret = az6027_usb_in_op(d, req, value, index, b, blen); | ||
501 | if (ret < 0) { | ||
502 | warn("usb in operation failed. (%d)", ret); | ||
503 | ret = -EINVAL; | ||
504 | } else { | ||
505 | if (b[0] == 0) | ||
506 | warn("Read CI IO error"); | ||
507 | |||
508 | ret = b[1]; | ||
509 | deb_info("read cam data = %x from 0x%x", b[1], value); | ||
510 | } | ||
511 | |||
512 | mutex_unlock(&state->ca_mutex); | ||
513 | return ret; | ||
514 | } | ||
515 | |||
516 | static int az6027_ci_write_cam_control(struct dvb_ca_en50221 *ca, | ||
517 | int slot, | ||
518 | u8 address, | ||
519 | u8 value) | ||
520 | { | ||
521 | struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; | ||
522 | struct az6027_device_state *state = (struct az6027_device_state *)d->priv; | ||
523 | |||
524 | int ret; | ||
525 | u8 req; | ||
526 | u16 value1; | ||
527 | u16 index; | ||
528 | int blen; | ||
529 | |||
530 | if (slot != 0) | ||
531 | return -EINVAL; | ||
532 | |||
533 | mutex_lock(&state->ca_mutex); | ||
534 | req = 0xC4; | ||
535 | value1 = address; | ||
536 | index = value; | ||
537 | blen = 0; | ||
538 | |||
539 | ret = az6027_usb_out_op(d, req, value1, index, NULL, blen); | ||
540 | if (ret != 0) { | ||
541 | warn("usb out operation failed. (%d)", ret); | ||
542 | goto failed; | ||
543 | } | ||
544 | |||
545 | failed: | ||
546 | mutex_unlock(&state->ca_mutex); | ||
547 | return ret; | ||
548 | } | ||
549 | |||
550 | static int CI_CamReady(struct dvb_ca_en50221 *ca, int slot) | ||
551 | { | ||
552 | struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; | ||
553 | |||
554 | int ret; | ||
555 | u8 req; | ||
556 | u16 value; | ||
557 | u16 index; | ||
558 | int blen; | ||
559 | u8 b[12]; | ||
560 | |||
561 | req = 0xC8; | ||
562 | value = 0; | ||
563 | index = 0; | ||
564 | blen = 1; | ||
565 | |||
566 | ret = az6027_usb_in_op(d, req, value, index, b, blen); | ||
567 | if (ret < 0) { | ||
568 | warn("usb in operation failed. (%d)", ret); | ||
569 | ret = -EIO; | ||
570 | } else{ | ||
571 | ret = b[0]; | ||
572 | } | ||
573 | return ret; | ||
574 | } | ||
575 | |||
576 | static int az6027_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot) | ||
577 | { | ||
578 | struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; | ||
579 | struct az6027_device_state *state = (struct az6027_device_state *)d->priv; | ||
580 | |||
581 | int ret, i; | ||
582 | u8 req; | ||
583 | u16 value; | ||
584 | u16 index; | ||
585 | int blen; | ||
586 | |||
587 | mutex_lock(&state->ca_mutex); | ||
588 | |||
589 | req = 0xC6; | ||
590 | value = 1; | ||
591 | index = 0; | ||
592 | blen = 0; | ||
593 | |||
594 | ret = az6027_usb_out_op(d, req, value, index, NULL, blen); | ||
595 | if (ret != 0) { | ||
596 | warn("usb out operation failed. (%d)", ret); | ||
597 | goto failed; | ||
598 | } | ||
599 | |||
600 | msleep(500); | ||
601 | req = 0xC6; | ||
602 | value = 0; | ||
603 | index = 0; | ||
604 | blen = 0; | ||
605 | |||
606 | ret = az6027_usb_out_op(d, req, value, index, NULL, blen); | ||
607 | if (ret != 0) { | ||
608 | warn("usb out operation failed. (%d)", ret); | ||
609 | goto failed; | ||
610 | } | ||
611 | |||
612 | for (i = 0; i < 15; i++) { | ||
613 | msleep(100); | ||
614 | |||
615 | if (CI_CamReady(ca, slot)) { | ||
616 | deb_info("CAM Ready"); | ||
617 | break; | ||
618 | } | ||
619 | } | ||
620 | msleep(5000); | ||
621 | |||
622 | failed: | ||
623 | mutex_unlock(&state->ca_mutex); | ||
624 | return ret; | ||
625 | } | ||
626 | |||
627 | static int az6027_ci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot) | ||
628 | { | ||
629 | return 0; | ||
630 | } | ||
631 | |||
632 | static int az6027_ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot) | ||
633 | { | ||
634 | struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; | ||
635 | struct az6027_device_state *state = (struct az6027_device_state *)d->priv; | ||
636 | |||
637 | int ret; | ||
638 | u8 req; | ||
639 | u16 value; | ||
640 | u16 index; | ||
641 | int blen; | ||
642 | |||
643 | deb_info("%s", __func__); | ||
644 | mutex_lock(&state->ca_mutex); | ||
645 | req = 0xC7; | ||
646 | value = 1; | ||
647 | index = 0; | ||
648 | blen = 0; | ||
649 | |||
650 | ret = az6027_usb_out_op(d, req, value, index, NULL, blen); | ||
651 | if (ret != 0) { | ||
652 | warn("usb out operation failed. (%d)", ret); | ||
653 | goto failed; | ||
654 | } | ||
655 | |||
656 | failed: | ||
657 | mutex_unlock(&state->ca_mutex); | ||
658 | return ret; | ||
659 | } | ||
660 | |||
661 | static int az6027_ci_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open) | ||
662 | { | ||
663 | struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data; | ||
664 | struct az6027_device_state *state = (struct az6027_device_state *)d->priv; | ||
665 | int ret; | ||
666 | u8 req; | ||
667 | u16 value; | ||
668 | u16 index; | ||
669 | int blen; | ||
670 | u8 b[12]; | ||
671 | |||
672 | mutex_lock(&state->ca_mutex); | ||
673 | |||
674 | req = 0xC5; | ||
675 | value = 0; | ||
676 | index = 0; | ||
677 | blen = 1; | ||
678 | |||
679 | ret = az6027_usb_in_op(d, req, value, index, b, blen); | ||
680 | if (ret < 0) { | ||
681 | warn("usb in operation failed. (%d)", ret); | ||
682 | ret = -EIO; | ||
683 | } else | ||
684 | ret = 0; | ||
685 | |||
686 | if (b[0] == 0) { | ||
687 | ret = 0; | ||
688 | |||
689 | } else if (b[0] == 1) { | ||
690 | ret = DVB_CA_EN50221_POLL_CAM_PRESENT | | ||
691 | DVB_CA_EN50221_POLL_CAM_READY; | ||
692 | } | ||
693 | |||
694 | mutex_unlock(&state->ca_mutex); | ||
695 | return ret; | ||
696 | } | ||
697 | |||
698 | |||
699 | static void az6027_ci_uninit(struct dvb_usb_device *d) | ||
700 | { | ||
701 | struct az6027_device_state *state; | ||
702 | |||
703 | deb_info("%s", __func__); | ||
704 | |||
705 | if (NULL == d) | ||
706 | return; | ||
707 | |||
708 | state = (struct az6027_device_state *)d->priv; | ||
709 | if (NULL == state) | ||
710 | return; | ||
711 | |||
712 | if (NULL == state->ca.data) | ||
713 | return; | ||
714 | |||
715 | dvb_ca_en50221_release(&state->ca); | ||
716 | |||
717 | memset(&state->ca, 0, sizeof(state->ca)); | ||
718 | } | ||
719 | |||
720 | |||
721 | static int az6027_ci_init(struct dvb_usb_adapter *a) | ||
722 | { | ||
723 | struct dvb_usb_device *d = a->dev; | ||
724 | struct az6027_device_state *state = (struct az6027_device_state *)d->priv; | ||
725 | int ret; | ||
726 | |||
727 | deb_info("%s", __func__); | ||
728 | |||
729 | mutex_init(&state->ca_mutex); | ||
730 | |||
731 | state->ca.owner = THIS_MODULE; | ||
732 | state->ca.read_attribute_mem = az6027_ci_read_attribute_mem; | ||
733 | state->ca.write_attribute_mem = az6027_ci_write_attribute_mem; | ||
734 | state->ca.read_cam_control = az6027_ci_read_cam_control; | ||
735 | state->ca.write_cam_control = az6027_ci_write_cam_control; | ||
736 | state->ca.slot_reset = az6027_ci_slot_reset; | ||
737 | state->ca.slot_shutdown = az6027_ci_slot_shutdown; | ||
738 | state->ca.slot_ts_enable = az6027_ci_slot_ts_enable; | ||
739 | state->ca.poll_slot_status = az6027_ci_poll_slot_status; | ||
740 | state->ca.data = d; | ||
741 | |||
742 | ret = dvb_ca_en50221_init(&a->dvb_adap, | ||
743 | &state->ca, | ||
744 | 0, /* flags */ | ||
745 | 1);/* n_slots */ | ||
746 | if (ret != 0) { | ||
747 | err("Cannot initialize CI: Error %d.", ret); | ||
748 | memset(&state->ca, 0, sizeof(state->ca)); | ||
749 | return ret; | ||
750 | } | ||
751 | |||
752 | deb_info("CI initialized."); | ||
753 | |||
754 | return 0; | ||
755 | } | ||
756 | |||
757 | /* | ||
758 | static int az6027_read_mac_addr(struct dvb_usb_device *d, u8 mac[6]) | ||
759 | { | ||
760 | az6027_usb_in_op(d, 0xb7, 6, 0, &mac[0], 6); | ||
761 | return 0; | ||
762 | } | ||
763 | */ | ||
764 | |||
765 | static int az6027_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | ||
766 | { | ||
767 | |||
768 | u8 buf; | ||
769 | int ret; | ||
770 | struct dvb_usb_adapter *adap = fe->dvb->priv; | ||
771 | |||
772 | struct i2c_msg i2c_msg = { | ||
773 | .addr = 0x99, | ||
774 | .flags = 0, | ||
775 | .buf = &buf, | ||
776 | .len = 1 | ||
777 | }; | ||
778 | |||
779 | /* | ||
780 | * 2 --18v | ||
781 | * 1 --13v | ||
782 | * 0 --off | ||
783 | */ | ||
784 | switch (voltage) { | ||
785 | case SEC_VOLTAGE_13: | ||
786 | buf = 1; | ||
787 | ret = i2c_transfer(&adap->dev->i2c_adap, &i2c_msg, 1); | ||
788 | break; | ||
789 | |||
790 | case SEC_VOLTAGE_18: | ||
791 | buf = 2; | ||
792 | ret = i2c_transfer(&adap->dev->i2c_adap, &i2c_msg, 1); | ||
793 | break; | ||
794 | |||
795 | case SEC_VOLTAGE_OFF: | ||
796 | buf = 0; | ||
797 | ret = i2c_transfer(&adap->dev->i2c_adap, &i2c_msg, 1); | ||
798 | break; | ||
799 | |||
800 | default: | ||
801 | return -EINVAL; | ||
802 | } | ||
803 | return 0; | ||
804 | } | ||
805 | |||
806 | |||
807 | static int az6027_frontend_poweron(struct dvb_usb_adapter *adap) | ||
808 | { | ||
809 | int ret; | ||
810 | u8 req; | ||
811 | u16 value; | ||
812 | u16 index; | ||
813 | int blen; | ||
814 | |||
815 | req = 0xBC; | ||
816 | value = 1; /* power on */ | ||
817 | index = 3; | ||
818 | blen = 0; | ||
819 | |||
820 | ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen); | ||
821 | if (ret != 0) | ||
822 | return -EIO; | ||
823 | |||
824 | return 0; | ||
825 | } | ||
826 | static int az6027_frontend_reset(struct dvb_usb_adapter *adap) | ||
827 | { | ||
828 | int ret; | ||
829 | u8 req; | ||
830 | u16 value; | ||
831 | u16 index; | ||
832 | int blen; | ||
833 | |||
834 | /* reset demodulator */ | ||
835 | req = 0xC0; | ||
836 | value = 1; /* high */ | ||
837 | index = 3; | ||
838 | blen = 0; | ||
839 | |||
840 | ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen); | ||
841 | if (ret != 0) | ||
842 | return -EIO; | ||
843 | |||
844 | req = 0xC0; | ||
845 | value = 0; /* low */ | ||
846 | index = 3; | ||
847 | blen = 0; | ||
848 | msleep_interruptible(200); | ||
849 | |||
850 | ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen); | ||
851 | if (ret != 0) | ||
852 | return -EIO; | ||
853 | |||
854 | msleep_interruptible(200); | ||
855 | |||
856 | req = 0xC0; | ||
857 | value = 1; /*high */ | ||
858 | index = 3; | ||
859 | blen = 0; | ||
860 | |||
861 | ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen); | ||
862 | if (ret != 0) | ||
863 | return -EIO; | ||
864 | |||
865 | msleep_interruptible(200); | ||
866 | return 0; | ||
867 | } | ||
868 | |||
869 | static int az6027_frontend_tsbypass(struct dvb_usb_adapter *adap, int onoff) | ||
870 | { | ||
871 | int ret; | ||
872 | u8 req; | ||
873 | u16 value; | ||
874 | u16 index; | ||
875 | int blen; | ||
876 | |||
877 | /* TS passthrough */ | ||
878 | req = 0xC7; | ||
879 | value = onoff; | ||
880 | index = 0; | ||
881 | blen = 0; | ||
882 | |||
883 | ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen); | ||
884 | if (ret != 0) | ||
885 | return -EIO; | ||
886 | |||
887 | return 0; | ||
888 | } | ||
889 | |||
890 | static int az6027_frontend_attach(struct dvb_usb_adapter *adap) | ||
891 | { | ||
892 | |||
893 | az6027_frontend_poweron(adap); | ||
894 | az6027_frontend_reset(adap); | ||
895 | |||
896 | deb_info("adap = %p, dev = %p\n", adap, adap->dev); | ||
897 | adap->fe = stb0899_attach(&az6027_stb0899_config, &adap->dev->i2c_adap); | ||
898 | |||
899 | if (adap->fe) { | ||
900 | deb_info("found STB0899 DVB-S/DVB-S2 frontend @0x%02x", az6027_stb0899_config.demod_address); | ||
901 | if (stb6100_attach(adap->fe, &az6027_stb6100_config, &adap->dev->i2c_adap)) { | ||
902 | deb_info("found STB6100 DVB-S/DVB-S2 frontend @0x%02x", az6027_stb6100_config.tuner_address); | ||
903 | adap->fe->ops.set_voltage = az6027_set_voltage; | ||
904 | az6027_ci_init(adap); | ||
905 | } else { | ||
906 | adap->fe = NULL; | ||
907 | } | ||
908 | } else | ||
909 | warn("no front-end attached\n"); | ||
910 | |||
911 | az6027_frontend_tsbypass(adap, 0); | ||
912 | |||
913 | return 0; | ||
914 | } | ||
915 | |||
916 | static struct dvb_usb_device_properties az6027_properties; | ||
917 | |||
918 | static void az6027_usb_disconnect(struct usb_interface *intf) | ||
919 | { | ||
920 | struct dvb_usb_device *d = usb_get_intfdata(intf); | ||
921 | az6027_ci_uninit(d); | ||
922 | dvb_usb_device_exit(intf); | ||
923 | } | ||
924 | |||
925 | |||
926 | static int az6027_usb_probe(struct usb_interface *intf, | ||
927 | const struct usb_device_id *id) | ||
928 | { | ||
929 | return dvb_usb_device_init(intf, | ||
930 | &az6027_properties, | ||
931 | THIS_MODULE, | ||
932 | NULL, | ||
933 | adapter_nr); | ||
934 | } | ||
935 | |||
936 | /* I2C */ | ||
937 | static int az6027_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) | ||
938 | { | ||
939 | struct dvb_usb_device *d = i2c_get_adapdata(adap); | ||
940 | int i = 0, j = 0, len = 0; | ||
941 | int ret; | ||
942 | u16 index; | ||
943 | u16 value; | ||
944 | int length; | ||
945 | u8 req; | ||
946 | u8 data[256]; | ||
947 | |||
948 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) | ||
949 | return -EAGAIN; | ||
950 | |||
951 | if (num > 2) | ||
952 | warn("more than 2 i2c messages at a time is not handled yet. TODO."); | ||
953 | |||
954 | for (i = 0; i < num; i++) { | ||
955 | |||
956 | if (msg[i].addr == 0x99) { | ||
957 | req = 0xBE; | ||
958 | index = 0; | ||
959 | value = msg[i].buf[0] & 0x00ff; | ||
960 | length = 1; | ||
961 | az6027_usb_out_op(d, req, value, index, data, length); | ||
962 | } | ||
963 | |||
964 | if (msg[i].addr == 0xd0) { | ||
965 | /* write/read request */ | ||
966 | if (i + 1 < num && (msg[i + 1].flags & I2C_M_RD)) { | ||
967 | req = 0xB9; | ||
968 | index = (((msg[i].buf[0] << 8) & 0xff00) | (msg[i].buf[1] & 0x00ff)); | ||
969 | value = msg[i].addr + (msg[i].len << 8); | ||
970 | length = msg[i + 1].len + 6; | ||
971 | ret = az6027_usb_in_op(d, req, value, index, data, length); | ||
972 | len = msg[i + 1].len; | ||
973 | for (j = 0; j < len; j++) | ||
974 | msg[i + 1].buf[j] = data[j + 5]; | ||
975 | |||
976 | i++; | ||
977 | } else { | ||
978 | |||
979 | if (msg[i].addr == 0xd0) { | ||
980 | /* demod 16bit addr */ | ||
981 | req = 0xBD; | ||
982 | index = (((msg[i].buf[0] << 8) & 0xff00) | (msg[i].buf[1] & 0x00ff)); | ||
983 | value = msg[i].addr + (2 << 8); | ||
984 | length = msg[i].len - 2; | ||
985 | len = msg[i].len - 2; | ||
986 | for (j = 0; j < len; j++) | ||
987 | data[j] = msg[i].buf[j + 2]; | ||
988 | |||
989 | } | ||
990 | az6027_usb_out_op(d, req, value, index, data, length); | ||
991 | } | ||
992 | } | ||
993 | |||
994 | if (msg[i].addr == 0xc0) { | ||
995 | if (msg[i].flags & I2C_M_RD) { | ||
996 | |||
997 | req = 0xB9; | ||
998 | index = 0x0; | ||
999 | value = msg[i].addr; | ||
1000 | length = msg[i].len + 6; | ||
1001 | ret = az6027_usb_in_op(d, req, value, index, data, length); | ||
1002 | len = msg[i].len; | ||
1003 | for (j = 0; j < len; j++) | ||
1004 | msg[i].buf[j] = data[j + 5]; | ||
1005 | |||
1006 | } else { | ||
1007 | |||
1008 | req = 0xBD; | ||
1009 | index = msg[i].buf[0] & 0x00FF; | ||
1010 | value = msg[i].addr + (1 << 8); | ||
1011 | length = msg[i].len - 1; | ||
1012 | len = msg[i].len - 1; | ||
1013 | |||
1014 | for (j = 0; j < len; j++) | ||
1015 | data[j] = msg[i].buf[j + 1]; | ||
1016 | |||
1017 | az6027_usb_out_op(d, req, value, index, data, length); | ||
1018 | } | ||
1019 | } | ||
1020 | } | ||
1021 | mutex_unlock(&d->i2c_mutex); | ||
1022 | |||
1023 | return i; | ||
1024 | } | ||
1025 | |||
1026 | |||
1027 | static u32 az6027_i2c_func(struct i2c_adapter *adapter) | ||
1028 | { | ||
1029 | return I2C_FUNC_I2C; | ||
1030 | } | ||
1031 | |||
1032 | static struct i2c_algorithm az6027_i2c_algo = { | ||
1033 | .master_xfer = az6027_i2c_xfer, | ||
1034 | .functionality = az6027_i2c_func, | ||
1035 | }; | ||
1036 | |||
1037 | int az6027_identify_state(struct usb_device *udev, | ||
1038 | struct dvb_usb_device_properties *props, | ||
1039 | struct dvb_usb_device_description **desc, | ||
1040 | int *cold) | ||
1041 | { | ||
1042 | u8 b[16]; | ||
1043 | s16 ret = usb_control_msg(udev, | ||
1044 | usb_rcvctrlpipe(udev, 0), | ||
1045 | 0xb7, | ||
1046 | USB_TYPE_VENDOR | USB_DIR_IN, | ||
1047 | 6, | ||
1048 | 0, | ||
1049 | b, | ||
1050 | 6, | ||
1051 | USB_CTRL_GET_TIMEOUT); | ||
1052 | |||
1053 | *cold = ret <= 0; | ||
1054 | |||
1055 | deb_info("cold: %d\n", *cold); | ||
1056 | return 0; | ||
1057 | } | ||
1058 | |||
1059 | |||
1060 | static struct usb_device_id az6027_usb_table[] = { | ||
1061 | { USB_DEVICE(USB_VID_AZUREWAVE, USB_PID_AZUREWAVE_AZ6027) }, | ||
1062 | { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_DVBS2CI) }, | ||
1063 | { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_HDCI) }, | ||
1064 | { }, | ||
1065 | }; | ||
1066 | |||
1067 | MODULE_DEVICE_TABLE(usb, az6027_usb_table); | ||
1068 | |||
1069 | static struct dvb_usb_device_properties az6027_properties = { | ||
1070 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | ||
1071 | .usb_ctrl = CYPRESS_FX2, | ||
1072 | .firmware = "dvb-usb-az6027-03.fw", | ||
1073 | .no_reconnect = 1, | ||
1074 | |||
1075 | .size_of_priv = sizeof(struct az6027_device_state), | ||
1076 | .identify_state = az6027_identify_state, | ||
1077 | .num_adapters = 1, | ||
1078 | .adapter = { | ||
1079 | { | ||
1080 | .streaming_ctrl = az6027_streaming_ctrl, | ||
1081 | .frontend_attach = az6027_frontend_attach, | ||
1082 | |||
1083 | /* parameter for the MPEG2-data transfer */ | ||
1084 | .stream = { | ||
1085 | .type = USB_BULK, | ||
1086 | .count = 10, | ||
1087 | .endpoint = 0x02, | ||
1088 | .u = { | ||
1089 | .bulk = { | ||
1090 | .buffersize = 4096, | ||
1091 | } | ||
1092 | } | ||
1093 | }, | ||
1094 | } | ||
1095 | }, | ||
1096 | /* | ||
1097 | .power_ctrl = az6027_power_ctrl, | ||
1098 | .read_mac_address = az6027_read_mac_addr, | ||
1099 | */ | ||
1100 | .rc_key_map = az6027_rc_keys, | ||
1101 | .rc_key_map_size = ARRAY_SIZE(az6027_rc_keys), | ||
1102 | .rc_interval = 400, | ||
1103 | .rc_query = az6027_rc_query, | ||
1104 | .i2c_algo = &az6027_i2c_algo, | ||
1105 | |||
1106 | .num_device_descs = 1, | ||
1107 | .devices = { | ||
1108 | { | ||
1109 | .name = "AZUREWAVE DVB-S/S2 USB2.0 (AZ6027)", | ||
1110 | .cold_ids = { &az6027_usb_table[0], NULL }, | ||
1111 | .warm_ids = { NULL }, | ||
1112 | }, | ||
1113 | { NULL }, | ||
1114 | } | ||
1115 | }; | ||
1116 | |||
1117 | /* usb specific object needed to register this driver with the usb subsystem */ | ||
1118 | static struct usb_driver az6027_usb_driver = { | ||
1119 | .name = "dvb_usb_az6027", | ||
1120 | .probe = az6027_usb_probe, | ||
1121 | .disconnect = az6027_usb_disconnect, | ||
1122 | .id_table = az6027_usb_table, | ||
1123 | }; | ||
1124 | |||
1125 | /* module stuff */ | ||
1126 | static int __init az6027_usb_module_init(void) | ||
1127 | { | ||
1128 | int result; | ||
1129 | |||
1130 | result = usb_register(&az6027_usb_driver); | ||
1131 | if (result) { | ||
1132 | err("usb_register failed. (%d)", result); | ||
1133 | return result; | ||
1134 | } | ||
1135 | |||
1136 | return 0; | ||
1137 | } | ||
1138 | |||
1139 | static void __exit az6027_usb_module_exit(void) | ||
1140 | { | ||
1141 | /* deregister this driver from the USB subsystem */ | ||
1142 | usb_deregister(&az6027_usb_driver); | ||
1143 | } | ||
1144 | |||
1145 | module_init(az6027_usb_module_init); | ||
1146 | module_exit(az6027_usb_module_exit); | ||
1147 | |||
1148 | MODULE_AUTHOR("Adams Xu <Adams.xu@azwave.com.cn>"); | ||
1149 | MODULE_DESCRIPTION("Driver for AZUREWAVE DVB-S/S2 USB2.0 (AZ6027)"); | ||
1150 | MODULE_VERSION("1.0"); | ||
1151 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/dvb-usb/az6027.h b/drivers/media/dvb/dvb-usb/az6027.h new file mode 100644 index 000000000000..f3afe17f3f3d --- /dev/null +++ b/drivers/media/dvb/dvb-usb/az6027.h | |||
@@ -0,0 +1,14 @@ | |||
1 | #ifndef _DVB_USB_VP6027_H_ | ||
2 | #define _DVB_USB_VP6027_H_ | ||
3 | |||
4 | #define DVB_USB_LOG_PREFIX "az6027" | ||
5 | #include "dvb-usb.h" | ||
6 | |||
7 | |||
8 | extern int dvb_usb_az6027_debug; | ||
9 | #define deb_info(args...) dprintk(dvb_usb_az6027_debug, 0x01, args) | ||
10 | #define deb_xfer(args...) dprintk(dvb_usb_az6027_debug, 0x02, args) | ||
11 | #define deb_rc(args...) dprintk(dvb_usb_az6027_debug, 0x04, args) | ||
12 | #define deb_fe(args...) dprintk(dvb_usb_az6027_debug, 0x08, args) | ||
13 | |||
14 | #endif | ||
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c index 05fb28e9c69e..a7b8405c291e 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.c +++ b/drivers/media/dvb/dvb-usb/cxusb.c | |||
@@ -1184,6 +1184,9 @@ static struct atbm8830_config mygica_d689_atbm8830_cfg = { | |||
1184 | .osc_clk_freq = 30400, /* in kHz */ | 1184 | .osc_clk_freq = 30400, /* in kHz */ |
1185 | .if_freq = 0, /* zero IF */ | 1185 | .if_freq = 0, /* zero IF */ |
1186 | .zif_swap_iq = 1, | 1186 | .zif_swap_iq = 1, |
1187 | .agc_min = 0x2E, | ||
1188 | .agc_max = 0x90, | ||
1189 | .agc_hold_loop = 0, | ||
1187 | }; | 1190 | }; |
1188 | 1191 | ||
1189 | static int cxusb_mygica_d689_frontend_attach(struct dvb_usb_adapter *adap) | 1192 | static int cxusb_mygica_d689_frontend_attach(struct dvb_usb_adapter *adap) |
diff --git a/drivers/media/dvb/dvb-usb/dib0700.h b/drivers/media/dvb/dvb-usb/dib0700.h index 495a90577c5f..83fc24a6c31a 100644 --- a/drivers/media/dvb/dvb-usb/dib0700.h +++ b/drivers/media/dvb/dvb-usb/dib0700.h | |||
@@ -42,7 +42,6 @@ struct dib0700_state { | |||
42 | u16 mt2060_if1[2]; | 42 | u16 mt2060_if1[2]; |
43 | u8 rc_toggle; | 43 | u8 rc_toggle; |
44 | u8 rc_counter; | 44 | u8 rc_counter; |
45 | u8 rc_func_version; | ||
46 | u8 is_dib7000pc; | 45 | u8 is_dib7000pc; |
47 | u8 fw_use_new_i2c_api; | 46 | u8 fw_use_new_i2c_api; |
48 | u8 disable_streaming_master_mode; | 47 | u8 disable_streaming_master_mode; |
diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c index 0d3c9a9a33be..4f961d2d1817 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_core.c +++ b/drivers/media/dvb/dvb-usb/dib0700_core.c | |||
@@ -471,14 +471,209 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) | |||
471 | return dib0700_ctrl_wr(adap->dev, b, 4); | 471 | return dib0700_ctrl_wr(adap->dev, b, 4); |
472 | } | 472 | } |
473 | 473 | ||
474 | /* Number of keypresses to ignore before start repeating */ | ||
475 | #define RC_REPEAT_DELAY_V1_20 10 | ||
476 | |||
477 | /* This is the structure of the RC response packet starting in firmware 1.20 */ | ||
478 | struct dib0700_rc_response { | ||
479 | u8 report_id; | ||
480 | u8 data_state; | ||
481 | u16 system; | ||
482 | u8 data; | ||
483 | u8 not_data; | ||
484 | }; | ||
485 | #define RC_MSG_SIZE_V1_20 6 | ||
486 | |||
487 | static void dib0700_rc_urb_completion(struct urb *purb) | ||
488 | { | ||
489 | struct dvb_usb_device *d = purb->context; | ||
490 | struct dvb_usb_rc_key *keymap; | ||
491 | struct dib0700_state *st; | ||
492 | struct dib0700_rc_response poll_reply; | ||
493 | u8 *buf; | ||
494 | int found = 0; | ||
495 | u32 event; | ||
496 | int state; | ||
497 | int i; | ||
498 | |||
499 | deb_info("%s()\n", __func__); | ||
500 | if (d == NULL) | ||
501 | return; | ||
502 | |||
503 | if (d->rc_input_dev == NULL) { | ||
504 | /* This will occur if disable_rc_polling=1 */ | ||
505 | usb_free_urb(purb); | ||
506 | return; | ||
507 | } | ||
508 | |||
509 | keymap = d->props.rc_key_map; | ||
510 | st = d->priv; | ||
511 | buf = (u8 *)purb->transfer_buffer; | ||
512 | |||
513 | if (purb->status < 0) { | ||
514 | deb_info("discontinuing polling\n"); | ||
515 | usb_free_urb(purb); | ||
516 | return; | ||
517 | } | ||
518 | |||
519 | if (purb->actual_length != RC_MSG_SIZE_V1_20) { | ||
520 | deb_info("malformed rc msg size=%d\n", purb->actual_length); | ||
521 | goto resubmit; | ||
522 | } | ||
523 | |||
524 | /* Set initial results in case we exit the function early */ | ||
525 | event = 0; | ||
526 | state = REMOTE_NO_KEY_PRESSED; | ||
527 | |||
528 | deb_data("IR raw %02X %02X %02X %02X %02X %02X (len %d)\n", buf[0], | ||
529 | buf[1], buf[2], buf[3], buf[4], buf[5], purb->actual_length); | ||
530 | |||
531 | switch (dvb_usb_dib0700_ir_proto) { | ||
532 | case 0: | ||
533 | /* NEC Protocol */ | ||
534 | poll_reply.report_id = 0; | ||
535 | poll_reply.data_state = 1; | ||
536 | poll_reply.system = buf[2]; | ||
537 | poll_reply.data = buf[4]; | ||
538 | poll_reply.not_data = buf[5]; | ||
539 | |||
540 | /* NEC protocol sends repeat code as 0 0 0 FF */ | ||
541 | if ((poll_reply.system == 0x00) && (poll_reply.data == 0x00) | ||
542 | && (poll_reply.not_data == 0xff)) { | ||
543 | poll_reply.data_state = 2; | ||
544 | break; | ||
545 | } | ||
546 | break; | ||
547 | default: | ||
548 | /* RC5 Protocol */ | ||
549 | poll_reply.report_id = buf[0]; | ||
550 | poll_reply.data_state = buf[1]; | ||
551 | poll_reply.system = (buf[2] << 8) | buf[3]; | ||
552 | poll_reply.data = buf[4]; | ||
553 | poll_reply.not_data = buf[5]; | ||
554 | break; | ||
555 | } | ||
556 | |||
557 | if ((poll_reply.data + poll_reply.not_data) != 0xff) { | ||
558 | /* Key failed integrity check */ | ||
559 | err("key failed integrity check: %04x %02x %02x", | ||
560 | poll_reply.system, | ||
561 | poll_reply.data, poll_reply.not_data); | ||
562 | goto resubmit; | ||
563 | } | ||
564 | |||
565 | deb_data("rid=%02x ds=%02x sm=%04x d=%02x nd=%02x\n", | ||
566 | poll_reply.report_id, poll_reply.data_state, | ||
567 | poll_reply.system, poll_reply.data, poll_reply.not_data); | ||
568 | |||
569 | /* Find the key in the map */ | ||
570 | for (i = 0; i < d->props.rc_key_map_size; i++) { | ||
571 | if (rc5_custom(&keymap[i]) == (poll_reply.system & 0xff) && | ||
572 | rc5_data(&keymap[i]) == poll_reply.data) { | ||
573 | event = keymap[i].event; | ||
574 | found = 1; | ||
575 | break; | ||
576 | } | ||
577 | } | ||
578 | |||
579 | if (found == 0) { | ||
580 | err("Unknown remote controller key: %04x %02x %02x", | ||
581 | poll_reply.system, poll_reply.data, poll_reply.not_data); | ||
582 | d->last_event = 0; | ||
583 | goto resubmit; | ||
584 | } | ||
585 | |||
586 | if (poll_reply.data_state == 1) { | ||
587 | /* New key hit */ | ||
588 | st->rc_counter = 0; | ||
589 | event = keymap[i].event; | ||
590 | state = REMOTE_KEY_PRESSED; | ||
591 | d->last_event = keymap[i].event; | ||
592 | } else if (poll_reply.data_state == 2) { | ||
593 | /* Key repeated */ | ||
594 | st->rc_counter++; | ||
595 | |||
596 | /* prevents unwanted double hits */ | ||
597 | if (st->rc_counter > RC_REPEAT_DELAY_V1_20) { | ||
598 | event = d->last_event; | ||
599 | state = REMOTE_KEY_PRESSED; | ||
600 | st->rc_counter = RC_REPEAT_DELAY_V1_20; | ||
601 | } | ||
602 | } else { | ||
603 | err("Unknown data state [%d]", poll_reply.data_state); | ||
604 | } | ||
605 | |||
606 | switch (state) { | ||
607 | case REMOTE_NO_KEY_PRESSED: | ||
608 | break; | ||
609 | case REMOTE_KEY_PRESSED: | ||
610 | deb_info("key pressed\n"); | ||
611 | d->last_event = event; | ||
612 | case REMOTE_KEY_REPEAT: | ||
613 | deb_info("key repeated\n"); | ||
614 | input_event(d->rc_input_dev, EV_KEY, event, 1); | ||
615 | input_sync(d->rc_input_dev); | ||
616 | input_event(d->rc_input_dev, EV_KEY, d->last_event, 0); | ||
617 | input_sync(d->rc_input_dev); | ||
618 | break; | ||
619 | default: | ||
620 | break; | ||
621 | } | ||
622 | |||
623 | resubmit: | ||
624 | /* Clean the buffer before we requeue */ | ||
625 | memset(purb->transfer_buffer, 0, RC_MSG_SIZE_V1_20); | ||
626 | |||
627 | /* Requeue URB */ | ||
628 | usb_submit_urb(purb, GFP_ATOMIC); | ||
629 | } | ||
630 | |||
474 | int dib0700_rc_setup(struct dvb_usb_device *d) | 631 | int dib0700_rc_setup(struct dvb_usb_device *d) |
475 | { | 632 | { |
633 | struct dib0700_state *st = d->priv; | ||
476 | u8 rc_setup[3] = {REQUEST_SET_RC, dvb_usb_dib0700_ir_proto, 0}; | 634 | u8 rc_setup[3] = {REQUEST_SET_RC, dvb_usb_dib0700_ir_proto, 0}; |
477 | int i = dib0700_ctrl_wr(d, rc_setup, 3); | 635 | struct urb *purb; |
636 | int ret; | ||
637 | int i; | ||
638 | |||
639 | if (d->props.rc_key_map == NULL) | ||
640 | return 0; | ||
641 | |||
642 | /* Set the IR mode */ | ||
643 | i = dib0700_ctrl_wr(d, rc_setup, 3); | ||
478 | if (i<0) { | 644 | if (i<0) { |
479 | err("ir protocol setup failed"); | 645 | err("ir protocol setup failed"); |
480 | return -1; | 646 | return -1; |
481 | } | 647 | } |
648 | |||
649 | if (st->fw_version < 0x10200) | ||
650 | return 0; | ||
651 | |||
652 | /* Starting in firmware 1.20, the RC info is provided on a bulk pipe */ | ||
653 | purb = usb_alloc_urb(0, GFP_KERNEL); | ||
654 | if (purb == NULL) { | ||
655 | err("rc usb alloc urb failed\n"); | ||
656 | return -1; | ||
657 | } | ||
658 | |||
659 | purb->transfer_buffer = kzalloc(RC_MSG_SIZE_V1_20, GFP_KERNEL); | ||
660 | if (purb->transfer_buffer == NULL) { | ||
661 | err("rc kzalloc failed\n"); | ||
662 | usb_free_urb(purb); | ||
663 | return -1; | ||
664 | } | ||
665 | |||
666 | purb->status = -EINPROGRESS; | ||
667 | usb_fill_bulk_urb(purb, d->udev, usb_rcvbulkpipe(d->udev, 1), | ||
668 | purb->transfer_buffer, RC_MSG_SIZE_V1_20, | ||
669 | dib0700_rc_urb_completion, d); | ||
670 | |||
671 | ret = usb_submit_urb(purb, GFP_ATOMIC); | ||
672 | if (ret != 0) { | ||
673 | err("rc submit urb failed\n"); | ||
674 | return -1; | ||
675 | } | ||
676 | |||
482 | return 0; | 677 | return 0; |
483 | } | 678 | } |
484 | 679 | ||
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index 44972d01bbd0..34eab05afc6c 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c | |||
@@ -472,20 +472,25 @@ static u8 rc_request[] = { REQUEST_POLL_RC, 0 }; | |||
472 | 472 | ||
473 | /* Number of keypresses to ignore before start repeating */ | 473 | /* Number of keypresses to ignore before start repeating */ |
474 | #define RC_REPEAT_DELAY 6 | 474 | #define RC_REPEAT_DELAY 6 |
475 | #define RC_REPEAT_DELAY_V1_20 10 | ||
476 | 475 | ||
477 | 476 | static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state) | |
478 | |||
479 | /* Used by firmware versions < 1.20 (deprecated) */ | ||
480 | static int dib0700_rc_query_legacy(struct dvb_usb_device *d, u32 *event, | ||
481 | int *state) | ||
482 | { | 477 | { |
483 | u8 key[4]; | 478 | u8 key[4]; |
484 | int i; | 479 | int i; |
485 | struct dvb_usb_rc_key *keymap = d->props.rc_key_map; | 480 | struct dvb_usb_rc_key *keymap = d->props.rc_key_map; |
486 | struct dib0700_state *st = d->priv; | 481 | struct dib0700_state *st = d->priv; |
482 | |||
487 | *event = 0; | 483 | *event = 0; |
488 | *state = REMOTE_NO_KEY_PRESSED; | 484 | *state = REMOTE_NO_KEY_PRESSED; |
485 | |||
486 | if (st->fw_version >= 0x10200) { | ||
487 | /* For 1.20 firmware , We need to keep the RC polling | ||
488 | callback so we can reuse the input device setup in | ||
489 | dvb-usb-remote.c. However, the actual work is being done | ||
490 | in the bulk URB completion handler. */ | ||
491 | return 0; | ||
492 | } | ||
493 | |||
489 | i=dib0700_ctrl_rd(d,rc_request,2,key,4); | 494 | i=dib0700_ctrl_rd(d,rc_request,2,key,4); |
490 | if (i<=0) { | 495 | if (i<=0) { |
491 | err("RC Query Failed"); | 496 | err("RC Query Failed"); |
@@ -557,149 +562,6 @@ static int dib0700_rc_query_legacy(struct dvb_usb_device *d, u32 *event, | |||
557 | return 0; | 562 | return 0; |
558 | } | 563 | } |
559 | 564 | ||
560 | /* This is the structure of the RC response packet starting in firmware 1.20 */ | ||
561 | struct dib0700_rc_response { | ||
562 | u8 report_id; | ||
563 | u8 data_state; | ||
564 | u16 system; | ||
565 | u8 data; | ||
566 | u8 not_data; | ||
567 | }; | ||
568 | |||
569 | /* This supports the new IR response format for firmware v1.20 */ | ||
570 | static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event, | ||
571 | int *state) | ||
572 | { | ||
573 | struct dvb_usb_rc_key *keymap = d->props.rc_key_map; | ||
574 | struct dib0700_state *st = d->priv; | ||
575 | struct dib0700_rc_response poll_reply; | ||
576 | u8 buf[6]; | ||
577 | int i; | ||
578 | int status; | ||
579 | int actlen; | ||
580 | int found = 0; | ||
581 | |||
582 | /* Set initial results in case we exit the function early */ | ||
583 | *event = 0; | ||
584 | *state = REMOTE_NO_KEY_PRESSED; | ||
585 | |||
586 | /* Firmware v1.20 provides RC data via bulk endpoint 1 */ | ||
587 | status = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, 1), buf, | ||
588 | sizeof(buf), &actlen, 50); | ||
589 | if (status < 0) { | ||
590 | /* No data available (meaning no key press) */ | ||
591 | return 0; | ||
592 | } | ||
593 | |||
594 | |||
595 | switch (dvb_usb_dib0700_ir_proto) { | ||
596 | case 0: | ||
597 | poll_reply.report_id = 0; | ||
598 | poll_reply.data_state = 1; | ||
599 | poll_reply.system = buf[2]; | ||
600 | poll_reply.data = buf[4]; | ||
601 | poll_reply.not_data = buf[5]; | ||
602 | |||
603 | /* NEC protocol sends repeat code as 0 0 0 FF */ | ||
604 | if ((poll_reply.system == 0x00) && (poll_reply.data == 0x00) | ||
605 | && (poll_reply.not_data == 0xff)) { | ||
606 | poll_reply.data_state = 2; | ||
607 | break; | ||
608 | } | ||
609 | break; | ||
610 | default: | ||
611 | if (actlen != sizeof(buf)) { | ||
612 | /* We didn't get back the 6 byte message we expected */ | ||
613 | err("Unexpected RC response size [%d]", actlen); | ||
614 | return -1; | ||
615 | } | ||
616 | |||
617 | poll_reply.report_id = buf[0]; | ||
618 | poll_reply.data_state = buf[1]; | ||
619 | poll_reply.system = (buf[2] << 8) | buf[3]; | ||
620 | poll_reply.data = buf[4]; | ||
621 | poll_reply.not_data = buf[5]; | ||
622 | |||
623 | break; | ||
624 | } | ||
625 | |||
626 | if ((poll_reply.data + poll_reply.not_data) != 0xff) { | ||
627 | /* Key failed integrity check */ | ||
628 | err("key failed integrity check: %04x %02x %02x", | ||
629 | poll_reply.system, | ||
630 | poll_reply.data, poll_reply.not_data); | ||
631 | return -1; | ||
632 | } | ||
633 | |||
634 | |||
635 | /* Find the key in the map */ | ||
636 | for (i = 0; i < d->props.rc_key_map_size; i++) { | ||
637 | if (rc5_custom(&keymap[i]) == (poll_reply.system & 0xff) && | ||
638 | rc5_data(&keymap[i]) == poll_reply.data) { | ||
639 | *event = keymap[i].event; | ||
640 | found = 1; | ||
641 | break; | ||
642 | } | ||
643 | } | ||
644 | |||
645 | if (found == 0) { | ||
646 | err("Unknown remote controller key: %04x %02x %02x", | ||
647 | poll_reply.system, | ||
648 | poll_reply.data, poll_reply.not_data); | ||
649 | d->last_event = 0; | ||
650 | return 0; | ||
651 | } | ||
652 | |||
653 | if (poll_reply.data_state == 1) { | ||
654 | /* New key hit */ | ||
655 | st->rc_counter = 0; | ||
656 | *event = keymap[i].event; | ||
657 | *state = REMOTE_KEY_PRESSED; | ||
658 | d->last_event = keymap[i].event; | ||
659 | } else if (poll_reply.data_state == 2) { | ||
660 | /* Key repeated */ | ||
661 | st->rc_counter++; | ||
662 | |||
663 | /* prevents unwanted double hits */ | ||
664 | if (st->rc_counter > RC_REPEAT_DELAY_V1_20) { | ||
665 | *event = d->last_event; | ||
666 | *state = REMOTE_KEY_PRESSED; | ||
667 | st->rc_counter = RC_REPEAT_DELAY_V1_20; | ||
668 | } | ||
669 | } else { | ||
670 | err("Unknown data state [%d]", poll_reply.data_state); | ||
671 | } | ||
672 | |||
673 | return 0; | ||
674 | } | ||
675 | |||
676 | static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state) | ||
677 | { | ||
678 | struct dib0700_state *st = d->priv; | ||
679 | |||
680 | /* Because some people may have improperly named firmware files, | ||
681 | let's figure out whether to use the new firmware call or the legacy | ||
682 | call based on the firmware version embedded in the file */ | ||
683 | if (st->rc_func_version == 0) { | ||
684 | u32 hwver, romver, ramver, fwtype; | ||
685 | int ret = dib0700_get_version(d, &hwver, &romver, &ramver, | ||
686 | &fwtype); | ||
687 | if (ret < 0) { | ||
688 | err("Could not determine version info"); | ||
689 | return -1; | ||
690 | } | ||
691 | if (ramver < 0x10200) | ||
692 | st->rc_func_version = 1; | ||
693 | else | ||
694 | st->rc_func_version = 2; | ||
695 | } | ||
696 | |||
697 | if (st->rc_func_version == 2) | ||
698 | return dib0700_rc_query_v1_20(d, event, state); | ||
699 | else | ||
700 | return dib0700_rc_query_legacy(d, event, state); | ||
701 | } | ||
702 | |||
703 | static struct dvb_usb_rc_key dib0700_rc_keys[] = { | 565 | static struct dvb_usb_rc_key dib0700_rc_keys[] = { |
704 | /* Key codes for the tiny Pinnacle remote*/ | 566 | /* Key codes for the tiny Pinnacle remote*/ |
705 | { 0x0700, KEY_MUTE }, | 567 | { 0x0700, KEY_MUTE }, |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index bc3581d58ced..ae8b57acfe05 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | |||
@@ -64,6 +64,8 @@ | |||
64 | #define USB_VID_HUMAX_COEX 0x10b9 | 64 | #define USB_VID_HUMAX_COEX 0x10b9 |
65 | #define USB_VID_774 0x7a69 | 65 | #define USB_VID_774 0x7a69 |
66 | #define USB_VID_EVOLUTEPC 0x1e59 | 66 | #define USB_VID_EVOLUTEPC 0x1e59 |
67 | #define USB_VID_AZUREWAVE 0x13d3 | ||
68 | #define USB_VID_TECHNISAT 0x14f7 | ||
67 | 69 | ||
68 | /* Product IDs */ | 70 | /* Product IDs */ |
69 | #define USB_PID_ADSTECH_USB2_COLD 0xa333 | 71 | #define USB_PID_ADSTECH_USB2_COLD 0xa333 |
@@ -138,6 +140,7 @@ | |||
138 | #define USB_PID_TWINHAN_VP7021_COLD 0x3207 | 140 | #define USB_PID_TWINHAN_VP7021_COLD 0x3207 |
139 | #define USB_PID_TWINHAN_VP7021_WARM 0x3208 | 141 | #define USB_PID_TWINHAN_VP7021_WARM 0x3208 |
140 | #define USB_PID_TINYTWIN 0x3226 | 142 | #define USB_PID_TINYTWIN 0x3226 |
143 | #define USB_PID_TINYTWIN_2 0xe402 | ||
141 | #define USB_PID_DNTV_TINYUSB2_COLD 0x3223 | 144 | #define USB_PID_DNTV_TINYUSB2_COLD 0x3223 |
142 | #define USB_PID_DNTV_TINYUSB2_WARM 0x3224 | 145 | #define USB_PID_DNTV_TINYUSB2_WARM 0x3224 |
143 | #define USB_PID_ULTIMA_TVBOX_COLD 0x8105 | 146 | #define USB_PID_ULTIMA_TVBOX_COLD 0x8105 |
@@ -209,6 +212,7 @@ | |||
209 | #define USB_PID_PINNACLE_PCTV71E 0x022b | 212 | #define USB_PID_PINNACLE_PCTV71E 0x022b |
210 | #define USB_PID_PINNACLE_PCTV72E 0x0236 | 213 | #define USB_PID_PINNACLE_PCTV72E 0x0236 |
211 | #define USB_PID_PINNACLE_PCTV73E 0x0237 | 214 | #define USB_PID_PINNACLE_PCTV73E 0x0237 |
215 | #define USB_PID_PINNACLE_PCTV310E 0x3211 | ||
212 | #define USB_PID_PINNACLE_PCTV801E 0x023a | 216 | #define USB_PID_PINNACLE_PCTV801E 0x023a |
213 | #define USB_PID_PINNACLE_PCTV801E_SE 0x023b | 217 | #define USB_PID_PINNACLE_PCTV801E_SE 0x023b |
214 | #define USB_PID_PINNACLE_PCTV73A 0x0243 | 218 | #define USB_PID_PINNACLE_PCTV73A 0x0243 |
@@ -248,6 +252,7 @@ | |||
248 | #define USB_PID_DIGIVOX_MINI_SL_WARM 0xe361 | 252 | #define USB_PID_DIGIVOX_MINI_SL_WARM 0xe361 |
249 | #define USB_PID_GRANDTEC_DVBT_USB2_COLD 0x0bc6 | 253 | #define USB_PID_GRANDTEC_DVBT_USB2_COLD 0x0bc6 |
250 | #define USB_PID_GRANDTEC_DVBT_USB2_WARM 0x0bc7 | 254 | #define USB_PID_GRANDTEC_DVBT_USB2_WARM 0x0bc7 |
255 | #define USB_PID_WINFAST_DTV2000DS 0x6a04 | ||
251 | #define USB_PID_WINFAST_DTV_DONGLE_COLD 0x6025 | 256 | #define USB_PID_WINFAST_DTV_DONGLE_COLD 0x6025 |
252 | #define USB_PID_WINFAST_DTV_DONGLE_WARM 0x6026 | 257 | #define USB_PID_WINFAST_DTV_DONGLE_WARM 0x6026 |
253 | #define USB_PID_WINFAST_DTV_DONGLE_STK7700P 0x6f00 | 258 | #define USB_PID_WINFAST_DTV_DONGLE_STK7700P 0x6f00 |
@@ -290,5 +295,7 @@ | |||
290 | #define USB_PID_FRIIO_WHITE 0x0001 | 295 | #define USB_PID_FRIIO_WHITE 0x0001 |
291 | #define USB_PID_TVWAY_PLUS 0x0002 | 296 | #define USB_PID_TVWAY_PLUS 0x0002 |
292 | #define USB_PID_SVEON_STV20 0xe39d | 297 | #define USB_PID_SVEON_STV20 0xe39d |
293 | 298 | #define USB_PID_AZUREWAVE_AZ6027 0x3275 | |
299 | #define USB_PID_TERRATEC_DVBS2CI 0x3275 | ||
300 | #define USB_PID_TECHNISAT_USB2_HDCI 0x0002 | ||
294 | #endif | 301 | #endif |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/drivers/media/dvb/dvb-usb/dvb-usb-init.c index e331db8c77b2..5d91f70d2d2d 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-init.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-init.c | |||
@@ -243,7 +243,7 @@ int dvb_usb_device_init(struct usb_interface *intf, | |||
243 | d = kzalloc(sizeof(struct dvb_usb_device),GFP_KERNEL); | 243 | d = kzalloc(sizeof(struct dvb_usb_device),GFP_KERNEL); |
244 | if (d == NULL) { | 244 | if (d == NULL) { |
245 | err("no memory for 'struct dvb_usb_device'"); | 245 | err("no memory for 'struct dvb_usb_device'"); |
246 | return ret; | 246 | return -ENOMEM; |
247 | } | 247 | } |
248 | 248 | ||
249 | d->udev = udev; | 249 | d->udev = udev; |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c index 6b5ded9e7d5d..a03ef7efec9a 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c | |||
@@ -107,6 +107,7 @@ static void dvb_usb_read_remote_control(struct work_struct *work) | |||
107 | case REMOTE_KEY_REPEAT: | 107 | case REMOTE_KEY_REPEAT: |
108 | deb_rc("key repeated\n"); | 108 | deb_rc("key repeated\n"); |
109 | input_event(d->rc_input_dev, EV_KEY, event, 1); | 109 | input_event(d->rc_input_dev, EV_KEY, event, 1); |
110 | input_sync(d->rc_input_dev); | ||
110 | input_event(d->rc_input_dev, EV_KEY, d->last_event, 0); | 111 | input_event(d->rc_input_dev, EV_KEY, d->last_event, 0); |
111 | input_sync(d->rc_input_dev); | 112 | input_sync(d->rc_input_dev); |
112 | break; | 113 | break; |
diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index 64132c0cf80d..accc65509b07 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* DVB USB framework compliant Linux driver for the | 1 | /* DVB USB framework compliant Linux driver for the |
2 | * DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101, | 2 | * DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101, |
3 | * TeVii S600, S630, S650 Cards | 3 | * TeVii S600, S630, S650, |
4 | * Prof 1100, 7500 Cards | ||
4 | * Copyright (C) 2008,2009 Igor M. Liplianin (liplianin@me.by) | 5 | * Copyright (C) 2008,2009 Igor M. Liplianin (liplianin@me.by) |
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
@@ -469,11 +470,13 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], | |||
469 | int num) | 470 | int num) |
470 | { | 471 | { |
471 | struct dvb_usb_device *d = i2c_get_adapdata(adap); | 472 | struct dvb_usb_device *d = i2c_get_adapdata(adap); |
473 | struct usb_device *udev; | ||
472 | int ret = 0; | 474 | int ret = 0; |
473 | int len, i, j; | 475 | int len, i, j; |
474 | 476 | ||
475 | if (!d) | 477 | if (!d) |
476 | return -ENODEV; | 478 | return -ENODEV; |
479 | udev = d->udev; | ||
477 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) | 480 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) |
478 | return -EAGAIN; | 481 | return -EAGAIN; |
479 | 482 | ||
@@ -488,8 +491,13 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], | |||
488 | } | 491 | } |
489 | case (DW2102_VOLTAGE_CTRL): { | 492 | case (DW2102_VOLTAGE_CTRL): { |
490 | u8 obuf[2]; | 493 | u8 obuf[2]; |
494 | |||
495 | obuf[0] = 1; | ||
496 | obuf[1] = msg[j].buf[1];/* off-on */ | ||
497 | ret = dw210x_op_rw(d->udev, 0x8a, 0, 0, | ||
498 | obuf, 2, DW210X_WRITE_MSG); | ||
491 | obuf[0] = 3; | 499 | obuf[0] = 3; |
492 | obuf[1] = msg[j].buf[0]; | 500 | obuf[1] = msg[j].buf[0];/* 13v-18v */ |
493 | ret = dw210x_op_rw(d->udev, 0x8a, 0, 0, | 501 | ret = dw210x_op_rw(d->udev, 0x8a, 0, 0, |
494 | obuf, 2, DW210X_WRITE_MSG); | 502 | obuf, 2, DW210X_WRITE_MSG); |
495 | break; | 503 | break; |
@@ -527,6 +535,17 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], | |||
527 | i += 16; | 535 | i += 16; |
528 | len -= 16; | 536 | len -= 16; |
529 | } while (len > 0); | 537 | } while (len > 0); |
538 | } else if ((udev->descriptor.idProduct == 0x7500) | ||
539 | && (j < (num - 1))) { | ||
540 | /* write register addr before read */ | ||
541 | u8 obuf[msg[j].len + 2]; | ||
542 | obuf[0] = msg[j + 1].len; | ||
543 | obuf[1] = (msg[j].addr << 1); | ||
544 | memcpy(obuf + 2, msg[j].buf, msg[j].len); | ||
545 | ret = dw210x_op_rw(d->udev, 0x92, 0, 0, | ||
546 | obuf, msg[j].len + 2, | ||
547 | DW210X_WRITE_MSG); | ||
548 | break; | ||
530 | } else { | 549 | } else { |
531 | /* write registers */ | 550 | /* write registers */ |
532 | u8 obuf[msg[j].len + 2]; | 551 | u8 obuf[msg[j].len + 2]; |
@@ -651,18 +670,25 @@ static int s6x0_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) | |||
651 | 670 | ||
652 | static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | 671 | static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) |
653 | { | 672 | { |
654 | static u8 command_13v[1] = {0x00}; | 673 | static u8 command_13v[] = {0x00, 0x01}; |
655 | static u8 command_18v[1] = {0x01}; | 674 | static u8 command_18v[] = {0x01, 0x01}; |
656 | struct i2c_msg msg[] = { | 675 | static u8 command_off[] = {0x00, 0x00}; |
657 | {.addr = DW2102_VOLTAGE_CTRL, .flags = 0, | 676 | struct i2c_msg msg = { |
658 | .buf = command_13v, .len = 1}, | 677 | .addr = DW2102_VOLTAGE_CTRL, |
678 | .flags = 0, | ||
679 | .buf = command_off, | ||
680 | .len = 2, | ||
659 | }; | 681 | }; |
660 | 682 | ||
661 | struct dvb_usb_adapter *udev_adap = | 683 | struct dvb_usb_adapter *udev_adap = |
662 | (struct dvb_usb_adapter *)(fe->dvb->priv); | 684 | (struct dvb_usb_adapter *)(fe->dvb->priv); |
663 | if (voltage == SEC_VOLTAGE_18) | 685 | if (voltage == SEC_VOLTAGE_18) |
664 | msg[0].buf = command_18v; | 686 | msg.buf = command_18v; |
665 | i2c_transfer(&udev_adap->dev->i2c_adap, msg, 1); | 687 | else if (voltage == SEC_VOLTAGE_13) |
688 | msg.buf = command_13v; | ||
689 | |||
690 | i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1); | ||
691 | |||
666 | return 0; | 692 | return 0; |
667 | } | 693 | } |
668 | 694 | ||
@@ -735,6 +761,18 @@ static struct stv6110_config dw2104_stv6110_config = { | |||
735 | .clk_div = 1, | 761 | .clk_div = 1, |
736 | }; | 762 | }; |
737 | 763 | ||
764 | static struct stv0900_config prof_7500_stv0900_config = { | ||
765 | .demod_address = 0x6a, | ||
766 | .demod_mode = 0, | ||
767 | .xtal = 27000000, | ||
768 | .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */ | ||
769 | .diseqc_mode = 2,/* 2/3 PWM */ | ||
770 | .tun1_maddress = 0,/* 0x60 */ | ||
771 | .tun1_adc = 0,/* 2 Vpp */ | ||
772 | .path1_mode = 3, | ||
773 | .tun1_type = 3, | ||
774 | }; | ||
775 | |||
738 | static int dw2104_frontend_attach(struct dvb_usb_adapter *d) | 776 | static int dw2104_frontend_attach(struct dvb_usb_adapter *d) |
739 | { | 777 | { |
740 | struct dvb_tuner_ops *tuner_ops = NULL; | 778 | struct dvb_tuner_ops *tuner_ops = NULL; |
@@ -882,6 +920,19 @@ static int s6x0_frontend_attach(struct dvb_usb_adapter *d) | |||
882 | return -EIO; | 920 | return -EIO; |
883 | } | 921 | } |
884 | 922 | ||
923 | static int prof_7500_frontend_attach(struct dvb_usb_adapter *d) | ||
924 | { | ||
925 | d->fe = dvb_attach(stv0900_attach, &prof_7500_stv0900_config, | ||
926 | &d->dev->i2c_adap, 0); | ||
927 | if (d->fe == NULL) | ||
928 | return -EIO; | ||
929 | d->fe->ops.set_voltage = dw210x_set_voltage; | ||
930 | |||
931 | info("Attached STV0900+STB6100A!\n"); | ||
932 | |||
933 | return 0; | ||
934 | } | ||
935 | |||
885 | static int dw2102_tuner_attach(struct dvb_usb_adapter *adap) | 936 | static int dw2102_tuner_attach(struct dvb_usb_adapter *adap) |
886 | { | 937 | { |
887 | dvb_attach(dvb_pll_attach, adap->fe, 0x60, | 938 | dvb_attach(dvb_pll_attach, adap->fe, 0x60, |
@@ -1073,6 +1124,7 @@ static struct usb_device_id dw2102_table[] = { | |||
1073 | {USB_DEVICE(0x9022, USB_PID_TEVII_S630)}, | 1124 | {USB_DEVICE(0x9022, USB_PID_TEVII_S630)}, |
1074 | {USB_DEVICE(0x3011, USB_PID_PROF_1100)}, | 1125 | {USB_DEVICE(0x3011, USB_PID_PROF_1100)}, |
1075 | {USB_DEVICE(0x9022, USB_PID_TEVII_S660)}, | 1126 | {USB_DEVICE(0x9022, USB_PID_TEVII_S660)}, |
1127 | {USB_DEVICE(0x3034, 0x7500)}, | ||
1076 | { } | 1128 | { } |
1077 | }; | 1129 | }; |
1078 | 1130 | ||
@@ -1387,9 +1439,30 @@ static struct dvb_usb_device_properties s6x0_properties = { | |||
1387 | } | 1439 | } |
1388 | }; | 1440 | }; |
1389 | 1441 | ||
1442 | struct dvb_usb_device_properties *p7500; | ||
1443 | static struct dvb_usb_device_description d7500 = { | ||
1444 | "Prof 7500 USB DVB-S2", | ||
1445 | {&dw2102_table[9], NULL}, | ||
1446 | {NULL}, | ||
1447 | }; | ||
1448 | |||
1390 | static int dw2102_probe(struct usb_interface *intf, | 1449 | static int dw2102_probe(struct usb_interface *intf, |
1391 | const struct usb_device_id *id) | 1450 | const struct usb_device_id *id) |
1392 | { | 1451 | { |
1452 | |||
1453 | p7500 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL); | ||
1454 | if (!p7500) | ||
1455 | return -ENOMEM; | ||
1456 | /* copy default structure */ | ||
1457 | memcpy(p7500, &s6x0_properties, | ||
1458 | sizeof(struct dvb_usb_device_properties)); | ||
1459 | /* fill only different fields */ | ||
1460 | p7500->firmware = "dvb-usb-p7500.fw"; | ||
1461 | p7500->devices[0] = d7500; | ||
1462 | p7500->rc_key_map = tbs_rc_keys; | ||
1463 | p7500->rc_key_map_size = ARRAY_SIZE(tbs_rc_keys); | ||
1464 | p7500->adapter->frontend_attach = prof_7500_frontend_attach; | ||
1465 | |||
1393 | if (0 == dvb_usb_device_init(intf, &dw2102_properties, | 1466 | if (0 == dvb_usb_device_init(intf, &dw2102_properties, |
1394 | THIS_MODULE, NULL, adapter_nr) || | 1467 | THIS_MODULE, NULL, adapter_nr) || |
1395 | 0 == dvb_usb_device_init(intf, &dw2104_properties, | 1468 | 0 == dvb_usb_device_init(intf, &dw2104_properties, |
@@ -1397,6 +1470,8 @@ static int dw2102_probe(struct usb_interface *intf, | |||
1397 | 0 == dvb_usb_device_init(intf, &dw3101_properties, | 1470 | 0 == dvb_usb_device_init(intf, &dw3101_properties, |
1398 | THIS_MODULE, NULL, adapter_nr) || | 1471 | THIS_MODULE, NULL, adapter_nr) || |
1399 | 0 == dvb_usb_device_init(intf, &s6x0_properties, | 1472 | 0 == dvb_usb_device_init(intf, &s6x0_properties, |
1473 | THIS_MODULE, NULL, adapter_nr) || | ||
1474 | 0 == dvb_usb_device_init(intf, p7500, | ||
1400 | THIS_MODULE, NULL, adapter_nr)) | 1475 | THIS_MODULE, NULL, adapter_nr)) |
1401 | return 0; | 1476 | return 0; |
1402 | 1477 | ||
@@ -1431,6 +1506,6 @@ MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); | |||
1431 | MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104," | 1506 | MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104," |
1432 | " DVB-C 3101 USB2.0," | 1507 | " DVB-C 3101 USB2.0," |
1433 | " TeVii S600, S630, S650, S660 USB2.0," | 1508 | " TeVii S600, S630, S650, S660 USB2.0," |
1434 | " Prof 1100 USB2.0 devices"); | 1509 | " Prof 1100, 7500 USB2.0 devices"); |
1435 | MODULE_VERSION("0.1"); | 1510 | MODULE_VERSION("0.1"); |
1436 | MODULE_LICENSE("GPL"); | 1511 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/media/dvb/dvb-usb/friio-fe.c b/drivers/media/dvb/dvb-usb/friio-fe.c index ebb7b9fd115b..d14bd227b502 100644 --- a/drivers/media/dvb/dvb-usb/friio-fe.c +++ b/drivers/media/dvb/dvb-usb/friio-fe.c | |||
@@ -366,7 +366,7 @@ static u8 init_code[][2] = { | |||
366 | {0x76, 0x0C}, | 366 | {0x76, 0x0C}, |
367 | }; | 367 | }; |
368 | 368 | ||
369 | const static int init_code_len = sizeof(init_code) / sizeof(u8[2]); | 369 | static const int init_code_len = sizeof(init_code) / sizeof(u8[2]); |
370 | 370 | ||
371 | static int jdvbt90502_init(struct dvb_frontend *fe) | 371 | static int jdvbt90502_init(struct dvb_frontend *fe) |
372 | { | 372 | { |
diff --git a/drivers/media/dvb/dvb-usb/m920x.c b/drivers/media/dvb/dvb-usb/m920x.c index ef9b7bed13ff..737ffa36ac9c 100644 --- a/drivers/media/dvb/dvb-usb/m920x.c +++ b/drivers/media/dvb/dvb-usb/m920x.c | |||
@@ -16,6 +16,9 @@ | |||
16 | #include "qt1010.h" | 16 | #include "qt1010.h" |
17 | #include "tda1004x.h" | 17 | #include "tda1004x.h" |
18 | #include "tda827x.h" | 18 | #include "tda827x.h" |
19 | |||
20 | #include <media/tuner.h> | ||
21 | #include "tuner-simple.h" | ||
19 | #include <asm/unaligned.h> | 22 | #include <asm/unaligned.h> |
20 | 23 | ||
21 | /* debug */ | 24 | /* debug */ |
@@ -158,11 +161,14 @@ static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state) | |||
158 | 161 | ||
159 | case 0x93: | 162 | case 0x93: |
160 | case 0x92: | 163 | case 0x92: |
164 | case 0x83: /* pinnacle PCTV310e */ | ||
165 | case 0x82: | ||
161 | m->rep_count = 0; | 166 | m->rep_count = 0; |
162 | *state = REMOTE_KEY_PRESSED; | 167 | *state = REMOTE_KEY_PRESSED; |
163 | goto unlock; | 168 | goto unlock; |
164 | 169 | ||
165 | case 0x91: | 170 | case 0x91: |
171 | case 0x81: /* pinnacle PCTV310e */ | ||
166 | /* prevent immediate auto-repeat */ | 172 | /* prevent immediate auto-repeat */ |
167 | if (++m->rep_count > 2) | 173 | if (++m->rep_count > 2) |
168 | *state = REMOTE_KEY_REPEAT; | 174 | *state = REMOTE_KEY_REPEAT; |
@@ -546,6 +552,14 @@ static int m920x_tda8275_61_tuner_attach(struct dvb_usb_adapter *adap) | |||
546 | return 0; | 552 | return 0; |
547 | } | 553 | } |
548 | 554 | ||
555 | static int m920x_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap) | ||
556 | { | ||
557 | dvb_attach(simple_tuner_attach, adap->fe, | ||
558 | &adap->dev->i2c_adap, 0x61, | ||
559 | TUNER_PHILIPS_FMD1216ME_MK3); | ||
560 | return 0; | ||
561 | } | ||
562 | |||
549 | /* device-specific initialization */ | 563 | /* device-specific initialization */ |
550 | static struct m920x_inits megasky_rc_init [] = { | 564 | static struct m920x_inits megasky_rc_init [] = { |
551 | { M9206_RC_INIT2, 0xa8 }, | 565 | { M9206_RC_INIT2, 0xa8 }, |
@@ -562,6 +576,18 @@ static struct m920x_inits tvwalkertwin_rc_init [] = { | |||
562 | { } /* terminating entry */ | 576 | { } /* terminating entry */ |
563 | }; | 577 | }; |
564 | 578 | ||
579 | static struct m920x_inits pinnacle310e_init[] = { | ||
580 | /* without these the tuner don't work */ | ||
581 | { 0xff20, 0x9b }, | ||
582 | { 0xff22, 0x70 }, | ||
583 | |||
584 | /* rc settings */ | ||
585 | { 0xff50, 0x80 }, | ||
586 | { M9206_RC_INIT1, 0x00 }, | ||
587 | { M9206_RC_INIT2, 0xff }, | ||
588 | { } /* terminating entry */ | ||
589 | }; | ||
590 | |||
565 | /* ir keymaps */ | 591 | /* ir keymaps */ |
566 | static struct dvb_usb_rc_key megasky_rc_keys [] = { | 592 | static struct dvb_usb_rc_key megasky_rc_keys [] = { |
567 | { 0x0012, KEY_POWER }, | 593 | { 0x0012, KEY_POWER }, |
@@ -602,11 +628,68 @@ static struct dvb_usb_rc_key tvwalkertwin_rc_keys [] = { | |||
602 | { 0x001e, KEY_VOLUMEUP }, | 628 | { 0x001e, KEY_VOLUMEUP }, |
603 | }; | 629 | }; |
604 | 630 | ||
631 | static struct dvb_usb_rc_key pinnacle310e_rc_keys[] = { | ||
632 | { 0x16, KEY_POWER }, | ||
633 | { 0x17, KEY_FAVORITES }, | ||
634 | { 0x0f, KEY_TEXT }, | ||
635 | { 0x48, KEY_MEDIA }, /* preview */ | ||
636 | { 0x1c, KEY_EPG }, | ||
637 | { 0x04, KEY_LIST }, /* record list */ | ||
638 | { 0x03, KEY_1 }, | ||
639 | { 0x01, KEY_2 }, | ||
640 | { 0x06, KEY_3 }, | ||
641 | { 0x09, KEY_4 }, | ||
642 | { 0x1d, KEY_5 }, | ||
643 | { 0x1f, KEY_6 }, | ||
644 | { 0x0d, KEY_7 }, | ||
645 | { 0x19, KEY_8 }, | ||
646 | { 0x1b, KEY_9 }, | ||
647 | { 0x15, KEY_0 }, | ||
648 | { 0x0c, KEY_CANCEL }, | ||
649 | { 0x4a, KEY_CLEAR }, | ||
650 | { 0x13, KEY_BACK }, | ||
651 | { 0x00, KEY_TAB }, | ||
652 | { 0x4b, KEY_UP }, | ||
653 | { 0x4e, KEY_LEFT }, | ||
654 | { 0x52, KEY_RIGHT }, | ||
655 | { 0x51, KEY_DOWN }, | ||
656 | { 0x4f, KEY_ENTER }, /* could also be KEY_OK */ | ||
657 | { 0x1e, KEY_VOLUMEUP }, | ||
658 | { 0x0a, KEY_VOLUMEDOWN }, | ||
659 | { 0x05, KEY_CHANNELUP }, | ||
660 | { 0x02, KEY_CHANNELDOWN }, | ||
661 | { 0x11, KEY_RECORD }, | ||
662 | { 0x14, KEY_PLAY }, | ||
663 | { 0x4c, KEY_PAUSE }, | ||
664 | { 0x1a, KEY_STOP }, | ||
665 | { 0x40, KEY_REWIND }, | ||
666 | { 0x12, KEY_FASTFORWARD }, | ||
667 | { 0x41, KEY_PREVIOUSSONG }, /* Replay */ | ||
668 | { 0x42, KEY_NEXTSONG }, /* Skip */ | ||
669 | { 0x54, KEY_CAMERA }, /* Capture */ | ||
670 | /* { 0x50, KEY_SAP }, */ /* Sap */ | ||
671 | { 0x47, KEY_CYCLEWINDOWS }, /* Pip */ | ||
672 | { 0x4d, KEY_SCREEN }, /* FullScreen */ | ||
673 | { 0x08, KEY_SUBTITLE }, | ||
674 | { 0x0e, KEY_MUTE }, | ||
675 | /* { 0x49, KEY_LR }, */ /* L/R */ | ||
676 | { 0x07, KEY_SLEEP }, /* Hibernate */ | ||
677 | { 0x08, KEY_MEDIA }, /* A/V */ | ||
678 | { 0x0e, KEY_MENU }, /* Recall */ | ||
679 | { 0x45, KEY_ZOOMIN }, | ||
680 | { 0x46, KEY_ZOOMOUT }, | ||
681 | { 0x18, KEY_TV }, /* Red */ | ||
682 | { 0x53, KEY_VCR }, /* Green */ | ||
683 | { 0x5e, KEY_SAT }, /* Yellow */ | ||
684 | { 0x5f, KEY_PLAYER }, /* Blue */ | ||
685 | }; | ||
686 | |||
605 | /* DVB USB Driver stuff */ | 687 | /* DVB USB Driver stuff */ |
606 | static struct dvb_usb_device_properties megasky_properties; | 688 | static struct dvb_usb_device_properties megasky_properties; |
607 | static struct dvb_usb_device_properties digivox_mini_ii_properties; | 689 | static struct dvb_usb_device_properties digivox_mini_ii_properties; |
608 | static struct dvb_usb_device_properties tvwalkertwin_properties; | 690 | static struct dvb_usb_device_properties tvwalkertwin_properties; |
609 | static struct dvb_usb_device_properties dposh_properties; | 691 | static struct dvb_usb_device_properties dposh_properties; |
692 | static struct dvb_usb_device_properties pinnacle_pctv310e_properties; | ||
610 | 693 | ||
611 | static int m920x_probe(struct usb_interface *intf, | 694 | static int m920x_probe(struct usb_interface *intf, |
612 | const struct usb_device_id *id) | 695 | const struct usb_device_id *id) |
@@ -652,6 +735,13 @@ static int m920x_probe(struct usb_interface *intf, | |||
652 | goto found; | 735 | goto found; |
653 | } | 736 | } |
654 | 737 | ||
738 | ret = dvb_usb_device_init(intf, &pinnacle_pctv310e_properties, | ||
739 | THIS_MODULE, &d, adapter_nr); | ||
740 | if (ret == 0) { | ||
741 | rc_init_seq = pinnacle310e_init; | ||
742 | goto found; | ||
743 | } | ||
744 | |||
655 | return ret; | 745 | return ret; |
656 | } else { | 746 | } else { |
657 | /* Another interface on a multi-tuner device */ | 747 | /* Another interface on a multi-tuner device */ |
@@ -682,6 +772,7 @@ static struct usb_device_id m920x_table [] = { | |||
682 | USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM) }, | 772 | USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM) }, |
683 | { USB_DEVICE(USB_VID_DPOSH, USB_PID_DPOSH_M9206_COLD) }, | 773 | { USB_DEVICE(USB_VID_DPOSH, USB_PID_DPOSH_M9206_COLD) }, |
684 | { USB_DEVICE(USB_VID_DPOSH, USB_PID_DPOSH_M9206_WARM) }, | 774 | { USB_DEVICE(USB_VID_DPOSH, USB_PID_DPOSH_M9206_WARM) }, |
775 | { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_PINNACLE_PCTV310E) }, | ||
685 | { } /* Terminating entry */ | 776 | { } /* Terminating entry */ |
686 | }; | 777 | }; |
687 | MODULE_DEVICE_TABLE (usb, m920x_table); | 778 | MODULE_DEVICE_TABLE (usb, m920x_table); |
@@ -895,6 +986,56 @@ static struct dvb_usb_device_properties dposh_properties = { | |||
895 | } | 986 | } |
896 | }; | 987 | }; |
897 | 988 | ||
989 | static struct dvb_usb_device_properties pinnacle_pctv310e_properties = { | ||
990 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | ||
991 | |||
992 | .usb_ctrl = DEVICE_SPECIFIC, | ||
993 | .download_firmware = NULL, | ||
994 | |||
995 | .rc_interval = 100, | ||
996 | .rc_key_map = pinnacle310e_rc_keys, | ||
997 | .rc_key_map_size = ARRAY_SIZE(pinnacle310e_rc_keys), | ||
998 | .rc_query = m920x_rc_query, | ||
999 | |||
1000 | .size_of_priv = sizeof(struct m920x_state), | ||
1001 | |||
1002 | .identify_state = m920x_identify_state, | ||
1003 | .num_adapters = 1, | ||
1004 | .adapter = {{ | ||
1005 | .caps = DVB_USB_ADAP_HAS_PID_FILTER | | ||
1006 | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, | ||
1007 | |||
1008 | .pid_filter_count = 8, | ||
1009 | .pid_filter = m920x_pid_filter, | ||
1010 | .pid_filter_ctrl = m920x_pid_filter_ctrl, | ||
1011 | |||
1012 | .frontend_attach = m920x_mt352_frontend_attach, | ||
1013 | .tuner_attach = m920x_fmd1216me_tuner_attach, | ||
1014 | |||
1015 | .stream = { | ||
1016 | .type = USB_ISOC, | ||
1017 | .count = 5, | ||
1018 | .endpoint = 0x84, | ||
1019 | .u = { | ||
1020 | .isoc = { | ||
1021 | .framesperurb = 128, | ||
1022 | .framesize = 564, | ||
1023 | .interval = 1, | ||
1024 | } | ||
1025 | } | ||
1026 | }, | ||
1027 | } }, | ||
1028 | .i2c_algo = &m920x_i2c_algo, | ||
1029 | |||
1030 | .num_device_descs = 1, | ||
1031 | .devices = { | ||
1032 | { "Pinnacle PCTV 310e", | ||
1033 | { &m920x_table[6], NULL }, | ||
1034 | { NULL }, | ||
1035 | } | ||
1036 | } | ||
1037 | }; | ||
1038 | |||
898 | static struct usb_driver m920x_driver = { | 1039 | static struct usb_driver m920x_driver = { |
899 | .name = "dvb_usb_m920x", | 1040 | .name = "dvb_usb_m920x", |
900 | .probe = m920x_probe, | 1041 | .probe = m920x_probe, |
diff --git a/drivers/media/dvb/dvb-usb/m920x.h b/drivers/media/dvb/dvb-usb/m920x.h index 37532890accd..3c061518ffc1 100644 --- a/drivers/media/dvb/dvb-usb/m920x.h +++ b/drivers/media/dvb/dvb-usb/m920x.h | |||
@@ -18,7 +18,7 @@ | |||
18 | #define M9206_FW 0x30 | 18 | #define M9206_FW 0x30 |
19 | 19 | ||
20 | #define M9206_MAX_FILTERS 8 | 20 | #define M9206_MAX_FILTERS 8 |
21 | #define M9206_MAX_ADAPTERS 2 | 21 | #define M9206_MAX_ADAPTERS 4 |
22 | 22 | ||
23 | /* | 23 | /* |
24 | sequences found in logs: | 24 | sequences found in logs: |
diff --git a/drivers/media/dvb/dvb-usb/opera1.c b/drivers/media/dvb/dvb-usb/opera1.c index d4e230941679..830557696ae6 100644 --- a/drivers/media/dvb/dvb-usb/opera1.c +++ b/drivers/media/dvb/dvb-usb/opera1.c | |||
@@ -138,7 +138,7 @@ static int opera1_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], | |||
138 | (msg[i].addr<<1)|(msg[i].flags&I2C_M_RD?0x01:0), | 138 | (msg[i].addr<<1)|(msg[i].flags&I2C_M_RD?0x01:0), |
139 | msg[i].buf, | 139 | msg[i].buf, |
140 | msg[i].len | 140 | msg[i].len |
141 | )!= msg[i].len)) { | 141 | )) != msg[i].len) { |
142 | break; | 142 | break; |
143 | } | 143 | } |
144 | if (dvb_usb_opera1_debug & 0x10) | 144 | if (dvb_usb_opera1_debug & 0x10) |
diff --git a/drivers/media/dvb/firewire/firedtv-1394.c b/drivers/media/dvb/firewire/firedtv-1394.c index 7c5459c27b75..c3e0ec2dcfca 100644 --- a/drivers/media/dvb/firewire/firedtv-1394.c +++ b/drivers/media/dvb/firewire/firedtv-1394.c | |||
@@ -90,13 +90,14 @@ static inline struct node_entry *node_of(struct firedtv *fdtv) | |||
90 | return container_of(fdtv->device, struct unit_directory, device)->ne; | 90 | return container_of(fdtv->device, struct unit_directory, device)->ne; |
91 | } | 91 | } |
92 | 92 | ||
93 | static int node_lock(struct firedtv *fdtv, u64 addr, __be32 data[]) | 93 | static int node_lock(struct firedtv *fdtv, u64 addr, void *data) |
94 | { | 94 | { |
95 | quadlet_t *d = data; | ||
95 | int ret; | 96 | int ret; |
96 | 97 | ||
97 | ret = hpsb_node_lock(node_of(fdtv), addr, EXTCODE_COMPARE_SWAP, | 98 | ret = hpsb_node_lock(node_of(fdtv), addr, |
98 | (__force quadlet_t *)&data[1], (__force quadlet_t)data[0]); | 99 | EXTCODE_COMPARE_SWAP, &d[1], d[0]); |
99 | data[0] = data[1]; | 100 | d[0] = d[1]; |
100 | 101 | ||
101 | return ret; | 102 | return ret; |
102 | } | 103 | } |
@@ -192,9 +193,13 @@ static int node_probe(struct device *dev) | |||
192 | int kv_len, err; | 193 | int kv_len, err; |
193 | void *kv_str; | 194 | void *kv_str; |
194 | 195 | ||
195 | kv_len = (ud->model_name_kv->value.leaf.len - 2) * sizeof(quadlet_t); | 196 | if (ud->model_name_kv) { |
196 | kv_str = CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(ud->model_name_kv); | 197 | kv_len = (ud->model_name_kv->value.leaf.len - 2) * 4; |
197 | 198 | kv_str = CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(ud->model_name_kv); | |
199 | } else { | ||
200 | kv_len = 0; | ||
201 | kv_str = NULL; | ||
202 | } | ||
198 | fdtv = fdtv_alloc(dev, &fdtv_1394_backend, kv_str, kv_len); | 203 | fdtv = fdtv_alloc(dev, &fdtv_1394_backend, kv_str, kv_len); |
199 | if (!fdtv) | 204 | if (!fdtv) |
200 | return -ENOMEM; | 205 | return -ENOMEM; |
diff --git a/drivers/media/dvb/firewire/firedtv-avc.c b/drivers/media/dvb/firewire/firedtv-avc.c index 50c42a4b972b..1b31bebc27d6 100644 --- a/drivers/media/dvb/firewire/firedtv-avc.c +++ b/drivers/media/dvb/firewire/firedtv-avc.c | |||
@@ -74,7 +74,6 @@ | |||
74 | #define EN50221_TAG_CA_INFO 0x9f8031 | 74 | #define EN50221_TAG_CA_INFO 0x9f8031 |
75 | 75 | ||
76 | struct avc_command_frame { | 76 | struct avc_command_frame { |
77 | int length; | ||
78 | u8 ctype; | 77 | u8 ctype; |
79 | u8 subunit; | 78 | u8 subunit; |
80 | u8 opcode; | 79 | u8 opcode; |
@@ -82,13 +81,27 @@ struct avc_command_frame { | |||
82 | }; | 81 | }; |
83 | 82 | ||
84 | struct avc_response_frame { | 83 | struct avc_response_frame { |
85 | int length; | ||
86 | u8 response; | 84 | u8 response; |
87 | u8 subunit; | 85 | u8 subunit; |
88 | u8 opcode; | 86 | u8 opcode; |
89 | u8 operand[509]; | 87 | u8 operand[509]; |
90 | }; | 88 | }; |
91 | 89 | ||
90 | #define LAST_OPERAND (509 - 1) | ||
91 | |||
92 | static inline void clear_operands(struct avc_command_frame *c, int from, int to) | ||
93 | { | ||
94 | memset(&c->operand[from], 0, to - from + 1); | ||
95 | } | ||
96 | |||
97 | static void pad_operands(struct avc_command_frame *c, int from) | ||
98 | { | ||
99 | int to = ALIGN(from, 4); | ||
100 | |||
101 | if (from <= to && to <= LAST_OPERAND) | ||
102 | clear_operands(c, from, to); | ||
103 | } | ||
104 | |||
92 | #define AVC_DEBUG_READ_DESCRIPTOR 0x0001 | 105 | #define AVC_DEBUG_READ_DESCRIPTOR 0x0001 |
93 | #define AVC_DEBUG_DSIT 0x0002 | 106 | #define AVC_DEBUG_DSIT 0x0002 |
94 | #define AVC_DEBUG_DSD 0x0004 | 107 | #define AVC_DEBUG_DSD 0x0004 |
@@ -202,78 +215,65 @@ static void debug_pmt(char *msg, int length) | |||
202 | 16, 1, msg, length, false); | 215 | 16, 1, msg, length, false); |
203 | } | 216 | } |
204 | 217 | ||
205 | static int __avc_write(struct firedtv *fdtv, | 218 | static int avc_write(struct firedtv *fdtv) |
206 | const struct avc_command_frame *c, struct avc_response_frame *r) | ||
207 | { | 219 | { |
208 | int err, retry; | 220 | int err, retry; |
209 | 221 | ||
210 | if (r) | 222 | fdtv->avc_reply_received = false; |
211 | fdtv->avc_reply_received = false; | ||
212 | 223 | ||
213 | for (retry = 0; retry < 6; retry++) { | 224 | for (retry = 0; retry < 6; retry++) { |
214 | if (unlikely(avc_debug)) | 225 | if (unlikely(avc_debug)) |
215 | debug_fcp(&c->ctype, c->length); | 226 | debug_fcp(fdtv->avc_data, fdtv->avc_data_length); |
216 | 227 | ||
217 | err = fdtv->backend->write(fdtv, FCP_COMMAND_REGISTER, | 228 | err = fdtv->backend->write(fdtv, FCP_COMMAND_REGISTER, |
218 | (void *)&c->ctype, c->length); | 229 | fdtv->avc_data, fdtv->avc_data_length); |
219 | if (err) { | 230 | if (err) { |
220 | fdtv->avc_reply_received = true; | ||
221 | dev_err(fdtv->device, "FCP command write failed\n"); | 231 | dev_err(fdtv->device, "FCP command write failed\n"); |
232 | |||
222 | return err; | 233 | return err; |
223 | } | 234 | } |
224 | 235 | ||
225 | if (!r) | ||
226 | return 0; | ||
227 | |||
228 | /* | 236 | /* |
229 | * AV/C specs say that answers should be sent within 150 ms. | 237 | * AV/C specs say that answers should be sent within 150 ms. |
230 | * Time out after 200 ms. | 238 | * Time out after 200 ms. |
231 | */ | 239 | */ |
232 | if (wait_event_timeout(fdtv->avc_wait, | 240 | if (wait_event_timeout(fdtv->avc_wait, |
233 | fdtv->avc_reply_received, | 241 | fdtv->avc_reply_received, |
234 | msecs_to_jiffies(200)) != 0) { | 242 | msecs_to_jiffies(200)) != 0) |
235 | r->length = fdtv->response_length; | ||
236 | memcpy(&r->response, fdtv->response, r->length); | ||
237 | |||
238 | return 0; | 243 | return 0; |
239 | } | ||
240 | } | 244 | } |
241 | dev_err(fdtv->device, "FCP response timed out\n"); | 245 | dev_err(fdtv->device, "FCP response timed out\n"); |
246 | |||
242 | return -ETIMEDOUT; | 247 | return -ETIMEDOUT; |
243 | } | 248 | } |
244 | 249 | ||
245 | static int avc_write(struct firedtv *fdtv, | 250 | static bool is_register_rc(struct avc_response_frame *r) |
246 | const struct avc_command_frame *c, struct avc_response_frame *r) | ||
247 | { | 251 | { |
248 | int ret; | 252 | return r->opcode == AVC_OPCODE_VENDOR && |
249 | 253 | r->operand[0] == SFE_VENDOR_DE_COMPANYID_0 && | |
250 | if (mutex_lock_interruptible(&fdtv->avc_mutex)) | 254 | r->operand[1] == SFE_VENDOR_DE_COMPANYID_1 && |
251 | return -EINTR; | 255 | r->operand[2] == SFE_VENDOR_DE_COMPANYID_2 && |
252 | 256 | r->operand[3] == SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL; | |
253 | ret = __avc_write(fdtv, c, r); | ||
254 | |||
255 | mutex_unlock(&fdtv->avc_mutex); | ||
256 | return ret; | ||
257 | } | 257 | } |
258 | 258 | ||
259 | int avc_recv(struct firedtv *fdtv, void *data, size_t length) | 259 | int avc_recv(struct firedtv *fdtv, void *data, size_t length) |
260 | { | 260 | { |
261 | struct avc_response_frame *r = | 261 | struct avc_response_frame *r = data; |
262 | data - offsetof(struct avc_response_frame, response); | ||
263 | 262 | ||
264 | if (unlikely(avc_debug)) | 263 | if (unlikely(avc_debug)) |
265 | debug_fcp(data, length); | 264 | debug_fcp(data, length); |
266 | 265 | ||
267 | if (length >= 8 && | 266 | if (length >= 8 && is_register_rc(r)) { |
268 | r->operand[0] == SFE_VENDOR_DE_COMPANYID_0 && | 267 | switch (r->response) { |
269 | r->operand[1] == SFE_VENDOR_DE_COMPANYID_1 && | 268 | case AVC_RESPONSE_CHANGED: |
270 | r->operand[2] == SFE_VENDOR_DE_COMPANYID_2 && | 269 | fdtv_handle_rc(fdtv, r->operand[4] << 8 | r->operand[5]); |
271 | r->operand[3] == SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL) { | ||
272 | if (r->response == AVC_RESPONSE_CHANGED) { | ||
273 | fdtv_handle_rc(fdtv, | ||
274 | r->operand[4] << 8 | r->operand[5]); | ||
275 | schedule_work(&fdtv->remote_ctrl_work); | 270 | schedule_work(&fdtv->remote_ctrl_work); |
276 | } else if (r->response != AVC_RESPONSE_INTERIM) { | 271 | break; |
272 | case AVC_RESPONSE_INTERIM: | ||
273 | if (is_register_rc((void *)fdtv->avc_data)) | ||
274 | goto wake; | ||
275 | break; | ||
276 | default: | ||
277 | dev_info(fdtv->device, | 277 | dev_info(fdtv->device, |
278 | "remote control result = %d\n", r->response); | 278 | "remote control result = %d\n", r->response); |
279 | } | 279 | } |
@@ -285,9 +285,9 @@ int avc_recv(struct firedtv *fdtv, void *data, size_t length) | |||
285 | return -EIO; | 285 | return -EIO; |
286 | } | 286 | } |
287 | 287 | ||
288 | memcpy(fdtv->response, data, length); | 288 | memcpy(fdtv->avc_data, data, length); |
289 | fdtv->response_length = length; | 289 | fdtv->avc_data_length = length; |
290 | 290 | wake: | |
291 | fdtv->avc_reply_received = true; | 291 | fdtv->avc_reply_received = true; |
292 | wake_up(&fdtv->avc_wait); | 292 | wake_up(&fdtv->avc_wait); |
293 | 293 | ||
@@ -318,10 +318,11 @@ static int add_pid_filter(struct firedtv *fdtv, u8 *operand) | |||
318 | * tuning command for setting the relative LNB frequency | 318 | * tuning command for setting the relative LNB frequency |
319 | * (not supported by the AVC standard) | 319 | * (not supported by the AVC standard) |
320 | */ | 320 | */ |
321 | static void avc_tuner_tuneqpsk(struct firedtv *fdtv, | 321 | static int avc_tuner_tuneqpsk(struct firedtv *fdtv, |
322 | struct dvb_frontend_parameters *params, | 322 | struct dvb_frontend_parameters *params) |
323 | struct avc_command_frame *c) | ||
324 | { | 323 | { |
324 | struct avc_command_frame *c = (void *)fdtv->avc_data; | ||
325 | |||
325 | c->opcode = AVC_OPCODE_VENDOR; | 326 | c->opcode = AVC_OPCODE_VENDOR; |
326 | 327 | ||
327 | c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; | 328 | c->operand[0] = SFE_VENDOR_DE_COMPANYID_0; |
@@ -370,16 +371,18 @@ static void avc_tuner_tuneqpsk(struct firedtv *fdtv, | |||
370 | c->operand[13] = 0x1; | 371 | c->operand[13] = 0x1; |
371 | c->operand[14] = 0xff; | 372 | c->operand[14] = 0xff; |
372 | c->operand[15] = 0xff; | 373 | c->operand[15] = 0xff; |
373 | c->length = 20; | 374 | |
375 | return 16; | ||
374 | } else { | 376 | } else { |
375 | c->length = 16; | 377 | return 13; |
376 | } | 378 | } |
377 | } | 379 | } |
378 | 380 | ||
379 | static void avc_tuner_dsd_dvb_c(struct firedtv *fdtv, | 381 | static int avc_tuner_dsd_dvb_c(struct firedtv *fdtv, |
380 | struct dvb_frontend_parameters *params, | 382 | struct dvb_frontend_parameters *params) |
381 | struct avc_command_frame *c) | ||
382 | { | 383 | { |
384 | struct avc_command_frame *c = (void *)fdtv->avc_data; | ||
385 | |||
383 | c->opcode = AVC_OPCODE_DSD; | 386 | c->opcode = AVC_OPCODE_DSD; |
384 | 387 | ||
385 | c->operand[0] = 0; /* source plug */ | 388 | c->operand[0] = 0; /* source plug */ |
@@ -440,15 +443,14 @@ static void avc_tuner_dsd_dvb_c(struct firedtv *fdtv, | |||
440 | c->operand[20] = 0x00; | 443 | c->operand[20] = 0x00; |
441 | c->operand[21] = 0x00; | 444 | c->operand[21] = 0x00; |
442 | 445 | ||
443 | /* Add PIDs to filter */ | 446 | return 22 + add_pid_filter(fdtv, &c->operand[22]); |
444 | c->length = ALIGN(22 + add_pid_filter(fdtv, &c->operand[22]) + 3, 4); | ||
445 | } | 447 | } |
446 | 448 | ||
447 | static void avc_tuner_dsd_dvb_t(struct firedtv *fdtv, | 449 | static int avc_tuner_dsd_dvb_t(struct firedtv *fdtv, |
448 | struct dvb_frontend_parameters *params, | 450 | struct dvb_frontend_parameters *params) |
449 | struct avc_command_frame *c) | ||
450 | { | 451 | { |
451 | struct dvb_ofdm_parameters *ofdm = ¶ms->u.ofdm; | 452 | struct dvb_ofdm_parameters *ofdm = ¶ms->u.ofdm; |
453 | struct avc_command_frame *c = (void *)fdtv->avc_data; | ||
452 | 454 | ||
453 | c->opcode = AVC_OPCODE_DSD; | 455 | c->opcode = AVC_OPCODE_DSD; |
454 | 456 | ||
@@ -543,55 +545,58 @@ static void avc_tuner_dsd_dvb_t(struct firedtv *fdtv, | |||
543 | c->operand[15] = 0x00; /* network_ID[0] */ | 545 | c->operand[15] = 0x00; /* network_ID[0] */ |
544 | c->operand[16] = 0x00; /* network_ID[1] */ | 546 | c->operand[16] = 0x00; /* network_ID[1] */ |
545 | 547 | ||
546 | /* Add PIDs to filter */ | 548 | return 17 + add_pid_filter(fdtv, &c->operand[17]); |
547 | c->length = ALIGN(17 + add_pid_filter(fdtv, &c->operand[17]) + 3, 4); | ||
548 | } | 549 | } |
549 | 550 | ||
550 | int avc_tuner_dsd(struct firedtv *fdtv, | 551 | int avc_tuner_dsd(struct firedtv *fdtv, |
551 | struct dvb_frontend_parameters *params) | 552 | struct dvb_frontend_parameters *params) |
552 | { | 553 | { |
553 | char buffer[sizeof(struct avc_command_frame)]; | 554 | struct avc_command_frame *c = (void *)fdtv->avc_data; |
554 | struct avc_command_frame *c = (void *)buffer; | 555 | int pos, ret; |
555 | struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */ | ||
556 | 556 | ||
557 | memset(c, 0, sizeof(*c)); | 557 | mutex_lock(&fdtv->avc_mutex); |
558 | 558 | ||
559 | c->ctype = AVC_CTYPE_CONTROL; | 559 | c->ctype = AVC_CTYPE_CONTROL; |
560 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; | 560 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; |
561 | 561 | ||
562 | switch (fdtv->type) { | 562 | switch (fdtv->type) { |
563 | case FIREDTV_DVB_S: | 563 | case FIREDTV_DVB_S: |
564 | case FIREDTV_DVB_S2: avc_tuner_tuneqpsk(fdtv, params, c); break; | 564 | case FIREDTV_DVB_S2: pos = avc_tuner_tuneqpsk(fdtv, params); break; |
565 | case FIREDTV_DVB_C: avc_tuner_dsd_dvb_c(fdtv, params, c); break; | 565 | case FIREDTV_DVB_C: pos = avc_tuner_dsd_dvb_c(fdtv, params); break; |
566 | case FIREDTV_DVB_T: avc_tuner_dsd_dvb_t(fdtv, params, c); break; | 566 | case FIREDTV_DVB_T: pos = avc_tuner_dsd_dvb_t(fdtv, params); break; |
567 | default: | 567 | default: |
568 | BUG(); | 568 | BUG(); |
569 | } | 569 | } |
570 | pad_operands(c, pos); | ||
570 | 571 | ||
571 | if (avc_write(fdtv, c, r) < 0) | 572 | fdtv->avc_data_length = ALIGN(3 + pos, 4); |
572 | return -EIO; | 573 | ret = avc_write(fdtv); |
573 | |||
574 | msleep(500); | ||
575 | #if 0 | 574 | #if 0 |
576 | /* FIXME: */ | 575 | /* |
577 | /* u8 *status was an out-parameter of avc_tuner_dsd, unused by caller */ | 576 | * FIXME: |
577 | * u8 *status was an out-parameter of avc_tuner_dsd, unused by caller. | ||
578 | * Check for AVC_RESPONSE_ACCEPTED here instead? | ||
579 | */ | ||
578 | if (status) | 580 | if (status) |
579 | *status = r->operand[2]; | 581 | *status = r->operand[2]; |
580 | #endif | 582 | #endif |
581 | return 0; | 583 | mutex_unlock(&fdtv->avc_mutex); |
584 | |||
585 | if (ret == 0) | ||
586 | msleep(500); | ||
587 | |||
588 | return ret; | ||
582 | } | 589 | } |
583 | 590 | ||
584 | int avc_tuner_set_pids(struct firedtv *fdtv, unsigned char pidc, u16 pid[]) | 591 | int avc_tuner_set_pids(struct firedtv *fdtv, unsigned char pidc, u16 pid[]) |
585 | { | 592 | { |
586 | char buffer[sizeof(struct avc_command_frame)]; | 593 | struct avc_command_frame *c = (void *)fdtv->avc_data; |
587 | struct avc_command_frame *c = (void *)buffer; | 594 | int ret, pos, k; |
588 | struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */ | ||
589 | int pos, k; | ||
590 | 595 | ||
591 | if (pidc > 16 && pidc != 0xff) | 596 | if (pidc > 16 && pidc != 0xff) |
592 | return -EINVAL; | 597 | return -EINVAL; |
593 | 598 | ||
594 | memset(c, 0, sizeof(*c)); | 599 | mutex_lock(&fdtv->avc_mutex); |
595 | 600 | ||
596 | c->ctype = AVC_CTYPE_CONTROL; | 601 | c->ctype = AVC_CTYPE_CONTROL; |
597 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; | 602 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; |
@@ -614,24 +619,27 @@ int avc_tuner_set_pids(struct firedtv *fdtv, unsigned char pidc, u16 pid[]) | |||
614 | c->operand[pos++] = 0x00; /* tableID */ | 619 | c->operand[pos++] = 0x00; /* tableID */ |
615 | c->operand[pos++] = 0x00; /* filter_length */ | 620 | c->operand[pos++] = 0x00; /* filter_length */ |
616 | } | 621 | } |
622 | pad_operands(c, pos); | ||
617 | 623 | ||
618 | c->length = ALIGN(3 + pos, 4); | 624 | fdtv->avc_data_length = ALIGN(3 + pos, 4); |
625 | ret = avc_write(fdtv); | ||
619 | 626 | ||
620 | if (avc_write(fdtv, c, r) < 0) | 627 | /* FIXME: check response code? */ |
621 | return -EIO; | ||
622 | 628 | ||
623 | msleep(50); | 629 | mutex_unlock(&fdtv->avc_mutex); |
624 | return 0; | 630 | |
631 | if (ret == 0) | ||
632 | msleep(50); | ||
633 | |||
634 | return ret; | ||
625 | } | 635 | } |
626 | 636 | ||
627 | int avc_tuner_get_ts(struct firedtv *fdtv) | 637 | int avc_tuner_get_ts(struct firedtv *fdtv) |
628 | { | 638 | { |
629 | char buffer[sizeof(struct avc_command_frame)]; | 639 | struct avc_command_frame *c = (void *)fdtv->avc_data; |
630 | struct avc_command_frame *c = (void *)buffer; | 640 | int ret, sl; |
631 | struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */ | ||
632 | int sl; | ||
633 | 641 | ||
634 | memset(c, 0, sizeof(*c)); | 642 | mutex_lock(&fdtv->avc_mutex); |
635 | 643 | ||
636 | c->ctype = AVC_CTYPE_CONTROL; | 644 | c->ctype = AVC_CTYPE_CONTROL; |
637 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; | 645 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; |
@@ -646,26 +654,33 @@ int avc_tuner_get_ts(struct firedtv *fdtv) | |||
646 | c->operand[4] = 0x00; /* antenna number */ | 654 | c->operand[4] = 0x00; /* antenna number */ |
647 | c->operand[5] = 0x0; /* system_specific_search_flags */ | 655 | c->operand[5] = 0x0; /* system_specific_search_flags */ |
648 | c->operand[6] = sl; /* system_specific_multiplex selection_length */ | 656 | c->operand[6] = sl; /* system_specific_multiplex selection_length */ |
649 | c->operand[7] = 0x00; /* valid_flags [0] */ | 657 | /* |
650 | c->operand[8] = 0x00; /* valid_flags [1] */ | 658 | * operand[7]: valid_flags[0] |
651 | c->operand[7 + sl] = 0x00; /* nr_of_dsit_sel_specs (always 0) */ | 659 | * operand[8]: valid_flags[1] |
660 | * operand[7 + sl]: nr_of_dsit_sel_specs (always 0) | ||
661 | */ | ||
662 | clear_operands(c, 7, 24); | ||
652 | 663 | ||
653 | c->length = fdtv->type == FIREDTV_DVB_T ? 24 : 28; | 664 | fdtv->avc_data_length = fdtv->type == FIREDTV_DVB_T ? 24 : 28; |
665 | ret = avc_write(fdtv); | ||
654 | 666 | ||
655 | if (avc_write(fdtv, c, r) < 0) | 667 | /* FIXME: check response code? */ |
656 | return -EIO; | ||
657 | 668 | ||
658 | msleep(250); | 669 | mutex_unlock(&fdtv->avc_mutex); |
659 | return 0; | 670 | |
671 | if (ret == 0) | ||
672 | msleep(250); | ||
673 | |||
674 | return ret; | ||
660 | } | 675 | } |
661 | 676 | ||
662 | int avc_identify_subunit(struct firedtv *fdtv) | 677 | int avc_identify_subunit(struct firedtv *fdtv) |
663 | { | 678 | { |
664 | char buffer[sizeof(struct avc_command_frame)]; | 679 | struct avc_command_frame *c = (void *)fdtv->avc_data; |
665 | struct avc_command_frame *c = (void *)buffer; | 680 | struct avc_response_frame *r = (void *)fdtv->avc_data; |
666 | struct avc_response_frame *r = (void *)buffer; | 681 | int ret; |
667 | 682 | ||
668 | memset(c, 0, sizeof(*c)); | 683 | mutex_lock(&fdtv->avc_mutex); |
669 | 684 | ||
670 | c->ctype = AVC_CTYPE_CONTROL; | 685 | c->ctype = AVC_CTYPE_CONTROL; |
671 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; | 686 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; |
@@ -678,31 +693,34 @@ int avc_identify_subunit(struct firedtv *fdtv) | |||
678 | c->operand[4] = 0x08; /* length lowbyte */ | 693 | c->operand[4] = 0x08; /* length lowbyte */ |
679 | c->operand[5] = 0x00; /* offset highbyte */ | 694 | c->operand[5] = 0x00; /* offset highbyte */ |
680 | c->operand[6] = 0x0d; /* offset lowbyte */ | 695 | c->operand[6] = 0x0d; /* offset lowbyte */ |
696 | clear_operands(c, 7, 8); /* padding */ | ||
681 | 697 | ||
682 | c->length = 12; | 698 | fdtv->avc_data_length = 12; |
683 | 699 | ret = avc_write(fdtv); | |
684 | if (avc_write(fdtv, c, r) < 0) | 700 | if (ret < 0) |
685 | return -EIO; | 701 | goto out; |
686 | 702 | ||
687 | if ((r->response != AVC_RESPONSE_STABLE && | 703 | if ((r->response != AVC_RESPONSE_STABLE && |
688 | r->response != AVC_RESPONSE_ACCEPTED) || | 704 | r->response != AVC_RESPONSE_ACCEPTED) || |
689 | (r->operand[3] << 8) + r->operand[4] != 8) { | 705 | (r->operand[3] << 8) + r->operand[4] != 8) { |
690 | dev_err(fdtv->device, "cannot read subunit identifier\n"); | 706 | dev_err(fdtv->device, "cannot read subunit identifier\n"); |
691 | return -EINVAL; | 707 | ret = -EINVAL; |
692 | } | 708 | } |
693 | return 0; | 709 | out: |
710 | mutex_unlock(&fdtv->avc_mutex); | ||
711 | |||
712 | return ret; | ||
694 | } | 713 | } |
695 | 714 | ||
696 | #define SIZEOF_ANTENNA_INPUT_INFO 22 | 715 | #define SIZEOF_ANTENNA_INPUT_INFO 22 |
697 | 716 | ||
698 | int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat) | 717 | int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat) |
699 | { | 718 | { |
700 | char buffer[sizeof(struct avc_command_frame)]; | 719 | struct avc_command_frame *c = (void *)fdtv->avc_data; |
701 | struct avc_command_frame *c = (void *)buffer; | 720 | struct avc_response_frame *r = (void *)fdtv->avc_data; |
702 | struct avc_response_frame *r = (void *)buffer; | 721 | int length, ret; |
703 | int length; | ||
704 | 722 | ||
705 | memset(c, 0, sizeof(*c)); | 723 | mutex_lock(&fdtv->avc_mutex); |
706 | 724 | ||
707 | c->ctype = AVC_CTYPE_CONTROL; | 725 | c->ctype = AVC_CTYPE_CONTROL; |
708 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; | 726 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; |
@@ -710,27 +728,30 @@ int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat) | |||
710 | 728 | ||
711 | c->operand[0] = DESCRIPTOR_TUNER_STATUS; | 729 | c->operand[0] = DESCRIPTOR_TUNER_STATUS; |
712 | c->operand[1] = 0xff; /* read_result_status */ | 730 | c->operand[1] = 0xff; /* read_result_status */ |
713 | c->operand[2] = 0x00; /* reserved */ | 731 | /* |
714 | c->operand[3] = 0; /* SIZEOF_ANTENNA_INPUT_INFO >> 8; */ | 732 | * operand[2]: reserved |
715 | c->operand[4] = 0; /* SIZEOF_ANTENNA_INPUT_INFO & 0xff; */ | 733 | * operand[3]: SIZEOF_ANTENNA_INPUT_INFO >> 8 |
716 | c->operand[5] = 0x00; | 734 | * operand[4]: SIZEOF_ANTENNA_INPUT_INFO & 0xff |
717 | c->operand[6] = 0x00; | 735 | */ |
718 | 736 | clear_operands(c, 2, 31); | |
719 | c->length = 12; | 737 | |
720 | 738 | fdtv->avc_data_length = 12; | |
721 | if (avc_write(fdtv, c, r) < 0) | 739 | ret = avc_write(fdtv); |
722 | return -EIO; | 740 | if (ret < 0) |
741 | goto out; | ||
723 | 742 | ||
724 | if (r->response != AVC_RESPONSE_STABLE && | 743 | if (r->response != AVC_RESPONSE_STABLE && |
725 | r->response != AVC_RESPONSE_ACCEPTED) { | 744 | r->response != AVC_RESPONSE_ACCEPTED) { |
726 | dev_err(fdtv->device, "cannot read tuner status\n"); | 745 | dev_err(fdtv->device, "cannot read tuner status\n"); |
727 | return -EINVAL; | 746 | ret = -EINVAL; |
747 | goto out; | ||
728 | } | 748 | } |
729 | 749 | ||
730 | length = r->operand[9]; | 750 | length = r->operand[9]; |
731 | if (r->operand[1] != 0x10 || length != SIZEOF_ANTENNA_INPUT_INFO) { | 751 | if (r->operand[1] != 0x10 || length != SIZEOF_ANTENNA_INPUT_INFO) { |
732 | dev_err(fdtv->device, "got invalid tuner status\n"); | 752 | dev_err(fdtv->device, "got invalid tuner status\n"); |
733 | return -EINVAL; | 753 | ret = -EINVAL; |
754 | goto out; | ||
734 | } | 755 | } |
735 | 756 | ||
736 | stat->active_system = r->operand[10]; | 757 | stat->active_system = r->operand[10]; |
@@ -766,20 +787,21 @@ int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat) | |||
766 | stat->ca_dvb_flag = r->operand[31] >> 3 & 1; | 787 | stat->ca_dvb_flag = r->operand[31] >> 3 & 1; |
767 | stat->ca_error_flag = r->operand[31] >> 2 & 1; | 788 | stat->ca_error_flag = r->operand[31] >> 2 & 1; |
768 | stat->ca_initialization_status = r->operand[31] >> 1 & 1; | 789 | stat->ca_initialization_status = r->operand[31] >> 1 & 1; |
790 | out: | ||
791 | mutex_unlock(&fdtv->avc_mutex); | ||
769 | 792 | ||
770 | return 0; | 793 | return ret; |
771 | } | 794 | } |
772 | 795 | ||
773 | int avc_lnb_control(struct firedtv *fdtv, char voltage, char burst, | 796 | int avc_lnb_control(struct firedtv *fdtv, char voltage, char burst, |
774 | char conttone, char nrdiseq, | 797 | char conttone, char nrdiseq, |
775 | struct dvb_diseqc_master_cmd *diseqcmd) | 798 | struct dvb_diseqc_master_cmd *diseqcmd) |
776 | { | 799 | { |
777 | char buffer[sizeof(struct avc_command_frame)]; | 800 | struct avc_command_frame *c = (void *)fdtv->avc_data; |
778 | struct avc_command_frame *c = (void *)buffer; | 801 | struct avc_response_frame *r = (void *)fdtv->avc_data; |
779 | struct avc_response_frame *r = (void *)buffer; | 802 | int pos, j, k, ret; |
780 | int i, j, k; | ||
781 | 803 | ||
782 | memset(c, 0, sizeof(*c)); | 804 | mutex_lock(&fdtv->avc_mutex); |
783 | 805 | ||
784 | c->ctype = AVC_CTYPE_CONTROL; | 806 | c->ctype = AVC_CTYPE_CONTROL; |
785 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; | 807 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; |
@@ -789,41 +811,41 @@ int avc_lnb_control(struct firedtv *fdtv, char voltage, char burst, | |||
789 | c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; | 811 | c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; |
790 | c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; | 812 | c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; |
791 | c->operand[3] = SFE_VENDOR_OPCODE_LNB_CONTROL; | 813 | c->operand[3] = SFE_VENDOR_OPCODE_LNB_CONTROL; |
792 | |||
793 | c->operand[4] = voltage; | 814 | c->operand[4] = voltage; |
794 | c->operand[5] = nrdiseq; | 815 | c->operand[5] = nrdiseq; |
795 | 816 | ||
796 | i = 6; | 817 | pos = 6; |
797 | |||
798 | for (j = 0; j < nrdiseq; j++) { | 818 | for (j = 0; j < nrdiseq; j++) { |
799 | c->operand[i++] = diseqcmd[j].msg_len; | 819 | c->operand[pos++] = diseqcmd[j].msg_len; |
800 | 820 | ||
801 | for (k = 0; k < diseqcmd[j].msg_len; k++) | 821 | for (k = 0; k < diseqcmd[j].msg_len; k++) |
802 | c->operand[i++] = diseqcmd[j].msg[k]; | 822 | c->operand[pos++] = diseqcmd[j].msg[k]; |
803 | } | 823 | } |
824 | c->operand[pos++] = burst; | ||
825 | c->operand[pos++] = conttone; | ||
826 | pad_operands(c, pos); | ||
804 | 827 | ||
805 | c->operand[i++] = burst; | 828 | fdtv->avc_data_length = ALIGN(3 + pos, 4); |
806 | c->operand[i++] = conttone; | 829 | ret = avc_write(fdtv); |
807 | 830 | if (ret < 0) | |
808 | c->length = ALIGN(3 + i, 4); | 831 | goto out; |
809 | |||
810 | if (avc_write(fdtv, c, r) < 0) | ||
811 | return -EIO; | ||
812 | 832 | ||
813 | if (r->response != AVC_RESPONSE_ACCEPTED) { | 833 | if (r->response != AVC_RESPONSE_ACCEPTED) { |
814 | dev_err(fdtv->device, "LNB control failed\n"); | 834 | dev_err(fdtv->device, "LNB control failed\n"); |
815 | return -EINVAL; | 835 | ret = -EINVAL; |
816 | } | 836 | } |
837 | out: | ||
838 | mutex_unlock(&fdtv->avc_mutex); | ||
817 | 839 | ||
818 | return 0; | 840 | return ret; |
819 | } | 841 | } |
820 | 842 | ||
821 | int avc_register_remote_control(struct firedtv *fdtv) | 843 | int avc_register_remote_control(struct firedtv *fdtv) |
822 | { | 844 | { |
823 | char buffer[sizeof(struct avc_command_frame)]; | 845 | struct avc_command_frame *c = (void *)fdtv->avc_data; |
824 | struct avc_command_frame *c = (void *)buffer; | 846 | int ret; |
825 | 847 | ||
826 | memset(c, 0, sizeof(*c)); | 848 | mutex_lock(&fdtv->avc_mutex); |
827 | 849 | ||
828 | c->ctype = AVC_CTYPE_NOTIFY; | 850 | c->ctype = AVC_CTYPE_NOTIFY; |
829 | c->subunit = AVC_SUBUNIT_TYPE_UNIT | 7; | 851 | c->subunit = AVC_SUBUNIT_TYPE_UNIT | 7; |
@@ -833,10 +855,16 @@ int avc_register_remote_control(struct firedtv *fdtv) | |||
833 | c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; | 855 | c->operand[1] = SFE_VENDOR_DE_COMPANYID_1; |
834 | c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; | 856 | c->operand[2] = SFE_VENDOR_DE_COMPANYID_2; |
835 | c->operand[3] = SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL; | 857 | c->operand[3] = SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL; |
858 | c->operand[4] = 0; /* padding */ | ||
859 | |||
860 | fdtv->avc_data_length = 8; | ||
861 | ret = avc_write(fdtv); | ||
836 | 862 | ||
837 | c->length = 8; | 863 | /* FIXME: check response code? */ |
838 | 864 | ||
839 | return avc_write(fdtv, c, NULL); | 865 | mutex_unlock(&fdtv->avc_mutex); |
866 | |||
867 | return ret; | ||
840 | } | 868 | } |
841 | 869 | ||
842 | void avc_remote_ctrl_work(struct work_struct *work) | 870 | void avc_remote_ctrl_work(struct work_struct *work) |
@@ -851,11 +879,10 @@ void avc_remote_ctrl_work(struct work_struct *work) | |||
851 | #if 0 /* FIXME: unused */ | 879 | #if 0 /* FIXME: unused */ |
852 | int avc_tuner_host2ca(struct firedtv *fdtv) | 880 | int avc_tuner_host2ca(struct firedtv *fdtv) |
853 | { | 881 | { |
854 | char buffer[sizeof(struct avc_command_frame)]; | 882 | struct avc_command_frame *c = (void *)fdtv->avc_data; |
855 | struct avc_command_frame *c = (void *)buffer; | 883 | int ret; |
856 | struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */ | ||
857 | 884 | ||
858 | memset(c, 0, sizeof(*c)); | 885 | mutex_lock(&fdtv->avc_mutex); |
859 | 886 | ||
860 | c->ctype = AVC_CTYPE_CONTROL; | 887 | c->ctype = AVC_CTYPE_CONTROL; |
861 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; | 888 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; |
@@ -867,15 +894,16 @@ int avc_tuner_host2ca(struct firedtv *fdtv) | |||
867 | c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA; | 894 | c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA; |
868 | c->operand[4] = 0; /* slot */ | 895 | c->operand[4] = 0; /* slot */ |
869 | c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */ | 896 | c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */ |
870 | c->operand[6] = 0; /* more/last */ | 897 | clear_operands(c, 6, 8); |
871 | c->operand[7] = 0; /* length */ | ||
872 | 898 | ||
873 | c->length = 12; | 899 | fdtv->avc_data_length = 12; |
900 | ret = avc_write(fdtv); | ||
874 | 901 | ||
875 | if (avc_write(fdtv, c, r) < 0) | 902 | /* FIXME: check response code? */ |
876 | return -EIO; | ||
877 | 903 | ||
878 | return 0; | 904 | mutex_unlock(&fdtv->avc_mutex); |
905 | |||
906 | return ret; | ||
879 | } | 907 | } |
880 | #endif | 908 | #endif |
881 | 909 | ||
@@ -906,12 +934,11 @@ static int get_ca_object_length(struct avc_response_frame *r) | |||
906 | 934 | ||
907 | int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len) | 935 | int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len) |
908 | { | 936 | { |
909 | char buffer[sizeof(struct avc_command_frame)]; | 937 | struct avc_command_frame *c = (void *)fdtv->avc_data; |
910 | struct avc_command_frame *c = (void *)buffer; | 938 | struct avc_response_frame *r = (void *)fdtv->avc_data; |
911 | struct avc_response_frame *r = (void *)buffer; | 939 | int pos, ret; |
912 | int pos; | ||
913 | 940 | ||
914 | memset(c, 0, sizeof(*c)); | 941 | mutex_lock(&fdtv->avc_mutex); |
915 | 942 | ||
916 | c->ctype = AVC_CTYPE_STATUS; | 943 | c->ctype = AVC_CTYPE_STATUS; |
917 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; | 944 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; |
@@ -923,11 +950,12 @@ int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len) | |||
923 | c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST; | 950 | c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST; |
924 | c->operand[4] = 0; /* slot */ | 951 | c->operand[4] = 0; /* slot */ |
925 | c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */ | 952 | c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */ |
953 | clear_operands(c, 6, LAST_OPERAND); | ||
926 | 954 | ||
927 | c->length = 12; | 955 | fdtv->avc_data_length = 12; |
928 | 956 | ret = avc_write(fdtv); | |
929 | if (avc_write(fdtv, c, r) < 0) | 957 | if (ret < 0) |
930 | return -EIO; | 958 | goto out; |
931 | 959 | ||
932 | /* FIXME: check response code and validate response data */ | 960 | /* FIXME: check response code and validate response data */ |
933 | 961 | ||
@@ -939,18 +967,19 @@ int avc_ca_app_info(struct firedtv *fdtv, char *app_info, unsigned int *len) | |||
939 | app_info[4] = 0x01; | 967 | app_info[4] = 0x01; |
940 | memcpy(&app_info[5], &r->operand[pos], 5 + r->operand[pos + 4]); | 968 | memcpy(&app_info[5], &r->operand[pos], 5 + r->operand[pos + 4]); |
941 | *len = app_info[3] + 4; | 969 | *len = app_info[3] + 4; |
970 | out: | ||
971 | mutex_unlock(&fdtv->avc_mutex); | ||
942 | 972 | ||
943 | return 0; | 973 | return ret; |
944 | } | 974 | } |
945 | 975 | ||
946 | int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len) | 976 | int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len) |
947 | { | 977 | { |
948 | char buffer[sizeof(struct avc_command_frame)]; | 978 | struct avc_command_frame *c = (void *)fdtv->avc_data; |
949 | struct avc_command_frame *c = (void *)buffer; | 979 | struct avc_response_frame *r = (void *)fdtv->avc_data; |
950 | struct avc_response_frame *r = (void *)buffer; | 980 | int pos, ret; |
951 | int pos; | ||
952 | 981 | ||
953 | memset(c, 0, sizeof(*c)); | 982 | mutex_lock(&fdtv->avc_mutex); |
954 | 983 | ||
955 | c->ctype = AVC_CTYPE_STATUS; | 984 | c->ctype = AVC_CTYPE_STATUS; |
956 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; | 985 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; |
@@ -962,11 +991,14 @@ int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len) | |||
962 | c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST; | 991 | c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST; |
963 | c->operand[4] = 0; /* slot */ | 992 | c->operand[4] = 0; /* slot */ |
964 | c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */ | 993 | c->operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; /* ca tag */ |
994 | clear_operands(c, 6, LAST_OPERAND); | ||
965 | 995 | ||
966 | c->length = 12; | 996 | fdtv->avc_data_length = 12; |
997 | ret = avc_write(fdtv); | ||
998 | if (ret < 0) | ||
999 | goto out; | ||
967 | 1000 | ||
968 | if (avc_write(fdtv, c, r) < 0) | 1001 | /* FIXME: check response code and validate response data */ |
969 | return -EIO; | ||
970 | 1002 | ||
971 | pos = get_ca_object_pos(r); | 1003 | pos = get_ca_object_pos(r); |
972 | app_info[0] = (EN50221_TAG_CA_INFO >> 16) & 0xff; | 1004 | app_info[0] = (EN50221_TAG_CA_INFO >> 16) & 0xff; |
@@ -976,17 +1008,18 @@ int avc_ca_info(struct firedtv *fdtv, char *app_info, unsigned int *len) | |||
976 | app_info[4] = r->operand[pos + 0]; | 1008 | app_info[4] = r->operand[pos + 0]; |
977 | app_info[5] = r->operand[pos + 1]; | 1009 | app_info[5] = r->operand[pos + 1]; |
978 | *len = app_info[3] + 4; | 1010 | *len = app_info[3] + 4; |
1011 | out: | ||
1012 | mutex_unlock(&fdtv->avc_mutex); | ||
979 | 1013 | ||
980 | return 0; | 1014 | return ret; |
981 | } | 1015 | } |
982 | 1016 | ||
983 | int avc_ca_reset(struct firedtv *fdtv) | 1017 | int avc_ca_reset(struct firedtv *fdtv) |
984 | { | 1018 | { |
985 | char buffer[sizeof(struct avc_command_frame)]; | 1019 | struct avc_command_frame *c = (void *)fdtv->avc_data; |
986 | struct avc_command_frame *c = (void *)buffer; | 1020 | int ret; |
987 | struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */ | ||
988 | 1021 | ||
989 | memset(c, 0, sizeof(*c)); | 1022 | mutex_lock(&fdtv->avc_mutex); |
990 | 1023 | ||
991 | c->ctype = AVC_CTYPE_CONTROL; | 1024 | c->ctype = AVC_CTYPE_CONTROL; |
992 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; | 1025 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; |
@@ -1002,19 +1035,20 @@ int avc_ca_reset(struct firedtv *fdtv) | |||
1002 | c->operand[7] = 1; /* length */ | 1035 | c->operand[7] = 1; /* length */ |
1003 | c->operand[8] = 0; /* force hardware reset */ | 1036 | c->operand[8] = 0; /* force hardware reset */ |
1004 | 1037 | ||
1005 | c->length = 12; | 1038 | fdtv->avc_data_length = 12; |
1039 | ret = avc_write(fdtv); | ||
1006 | 1040 | ||
1007 | if (avc_write(fdtv, c, r) < 0) | 1041 | /* FIXME: check response code? */ |
1008 | return -EIO; | ||
1009 | 1042 | ||
1010 | return 0; | 1043 | mutex_unlock(&fdtv->avc_mutex); |
1044 | |||
1045 | return ret; | ||
1011 | } | 1046 | } |
1012 | 1047 | ||
1013 | int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length) | 1048 | int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length) |
1014 | { | 1049 | { |
1015 | char buffer[sizeof(struct avc_command_frame)]; | 1050 | struct avc_command_frame *c = (void *)fdtv->avc_data; |
1016 | struct avc_command_frame *c = (void *)buffer; | 1051 | struct avc_response_frame *r = (void *)fdtv->avc_data; |
1017 | struct avc_response_frame *r = (void *)buffer; | ||
1018 | int list_management; | 1052 | int list_management; |
1019 | int program_info_length; | 1053 | int program_info_length; |
1020 | int pmt_cmd_id; | 1054 | int pmt_cmd_id; |
@@ -1022,11 +1056,12 @@ int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length) | |||
1022 | int write_pos; | 1056 | int write_pos; |
1023 | int es_info_length; | 1057 | int es_info_length; |
1024 | int crc32_csum; | 1058 | int crc32_csum; |
1059 | int ret; | ||
1025 | 1060 | ||
1026 | if (unlikely(avc_debug & AVC_DEBUG_APPLICATION_PMT)) | 1061 | if (unlikely(avc_debug & AVC_DEBUG_APPLICATION_PMT)) |
1027 | debug_pmt(msg, length); | 1062 | debug_pmt(msg, length); |
1028 | 1063 | ||
1029 | memset(c, 0, sizeof(*c)); | 1064 | mutex_lock(&fdtv->avc_mutex); |
1030 | 1065 | ||
1031 | c->ctype = AVC_CTYPE_CONTROL; | 1066 | c->ctype = AVC_CTYPE_CONTROL; |
1032 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; | 1067 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; |
@@ -1058,7 +1093,7 @@ int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length) | |||
1058 | 1093 | ||
1059 | c->operand[12] = 0x02; /* Table id=2 */ | 1094 | c->operand[12] = 0x02; /* Table id=2 */ |
1060 | c->operand[13] = 0x80; /* Section syntax + length */ | 1095 | c->operand[13] = 0x80; /* Section syntax + length */ |
1061 | /* c->operand[14] = XXXprogram_info_length + 12; */ | 1096 | |
1062 | c->operand[15] = msg[1]; /* Program number */ | 1097 | c->operand[15] = msg[1]; /* Program number */ |
1063 | c->operand[16] = msg[2]; | 1098 | c->operand[16] = msg[2]; |
1064 | c->operand[17] = 0x01; /* Version number=0 + current/next=1 */ | 1099 | c->operand[17] = 0x01; /* Version number=0 + current/next=1 */ |
@@ -1106,12 +1141,7 @@ int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length) | |||
1106 | write_pos += es_info_length; | 1141 | write_pos += es_info_length; |
1107 | } | 1142 | } |
1108 | } | 1143 | } |
1109 | 1144 | write_pos += 4; /* CRC */ | |
1110 | /* CRC */ | ||
1111 | c->operand[write_pos++] = 0x00; | ||
1112 | c->operand[write_pos++] = 0x00; | ||
1113 | c->operand[write_pos++] = 0x00; | ||
1114 | c->operand[write_pos++] = 0x00; | ||
1115 | 1145 | ||
1116 | c->operand[7] = 0x82; | 1146 | c->operand[7] = 0x82; |
1117 | c->operand[8] = (write_pos - 10) >> 8; | 1147 | c->operand[8] = (write_pos - 10) >> 8; |
@@ -1123,28 +1153,31 @@ int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length) | |||
1123 | c->operand[write_pos - 3] = (crc32_csum >> 16) & 0xff; | 1153 | c->operand[write_pos - 3] = (crc32_csum >> 16) & 0xff; |
1124 | c->operand[write_pos - 2] = (crc32_csum >> 8) & 0xff; | 1154 | c->operand[write_pos - 2] = (crc32_csum >> 8) & 0xff; |
1125 | c->operand[write_pos - 1] = (crc32_csum >> 0) & 0xff; | 1155 | c->operand[write_pos - 1] = (crc32_csum >> 0) & 0xff; |
1156 | pad_operands(c, write_pos); | ||
1126 | 1157 | ||
1127 | c->length = ALIGN(3 + write_pos, 4); | 1158 | fdtv->avc_data_length = ALIGN(3 + write_pos, 4); |
1128 | 1159 | ret = avc_write(fdtv); | |
1129 | if (avc_write(fdtv, c, r) < 0) | 1160 | if (ret < 0) |
1130 | return -EIO; | 1161 | goto out; |
1131 | 1162 | ||
1132 | if (r->response != AVC_RESPONSE_ACCEPTED) { | 1163 | if (r->response != AVC_RESPONSE_ACCEPTED) { |
1133 | dev_err(fdtv->device, | 1164 | dev_err(fdtv->device, |
1134 | "CA PMT failed with response 0x%x\n", r->response); | 1165 | "CA PMT failed with response 0x%x\n", r->response); |
1135 | return -EFAULT; | 1166 | ret = -EFAULT; |
1136 | } | 1167 | } |
1168 | out: | ||
1169 | mutex_unlock(&fdtv->avc_mutex); | ||
1137 | 1170 | ||
1138 | return 0; | 1171 | return ret; |
1139 | } | 1172 | } |
1140 | 1173 | ||
1141 | int avc_ca_get_time_date(struct firedtv *fdtv, int *interval) | 1174 | int avc_ca_get_time_date(struct firedtv *fdtv, int *interval) |
1142 | { | 1175 | { |
1143 | char buffer[sizeof(struct avc_command_frame)]; | 1176 | struct avc_command_frame *c = (void *)fdtv->avc_data; |
1144 | struct avc_command_frame *c = (void *)buffer; | 1177 | struct avc_response_frame *r = (void *)fdtv->avc_data; |
1145 | struct avc_response_frame *r = (void *)buffer; | 1178 | int ret; |
1146 | 1179 | ||
1147 | memset(c, 0, sizeof(*c)); | 1180 | mutex_lock(&fdtv->avc_mutex); |
1148 | 1181 | ||
1149 | c->ctype = AVC_CTYPE_STATUS; | 1182 | c->ctype = AVC_CTYPE_STATUS; |
1150 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; | 1183 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; |
@@ -1156,28 +1189,28 @@ int avc_ca_get_time_date(struct firedtv *fdtv, int *interval) | |||
1156 | c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST; | 1189 | c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST; |
1157 | c->operand[4] = 0; /* slot */ | 1190 | c->operand[4] = 0; /* slot */ |
1158 | c->operand[5] = SFE_VENDOR_TAG_CA_DATE_TIME; /* ca tag */ | 1191 | c->operand[5] = SFE_VENDOR_TAG_CA_DATE_TIME; /* ca tag */ |
1159 | c->operand[6] = 0; /* more/last */ | 1192 | clear_operands(c, 6, LAST_OPERAND); |
1160 | c->operand[7] = 0; /* length */ | ||
1161 | 1193 | ||
1162 | c->length = 12; | 1194 | fdtv->avc_data_length = 12; |
1163 | 1195 | ret = avc_write(fdtv); | |
1164 | if (avc_write(fdtv, c, r) < 0) | 1196 | if (ret < 0) |
1165 | return -EIO; | 1197 | goto out; |
1166 | 1198 | ||
1167 | /* FIXME: check response code and validate response data */ | 1199 | /* FIXME: check response code and validate response data */ |
1168 | 1200 | ||
1169 | *interval = r->operand[get_ca_object_pos(r)]; | 1201 | *interval = r->operand[get_ca_object_pos(r)]; |
1202 | out: | ||
1203 | mutex_unlock(&fdtv->avc_mutex); | ||
1170 | 1204 | ||
1171 | return 0; | 1205 | return ret; |
1172 | } | 1206 | } |
1173 | 1207 | ||
1174 | int avc_ca_enter_menu(struct firedtv *fdtv) | 1208 | int avc_ca_enter_menu(struct firedtv *fdtv) |
1175 | { | 1209 | { |
1176 | char buffer[sizeof(struct avc_command_frame)]; | 1210 | struct avc_command_frame *c = (void *)fdtv->avc_data; |
1177 | struct avc_command_frame *c = (void *)buffer; | 1211 | int ret; |
1178 | struct avc_response_frame *r = (void *)buffer; /* FIXME: unused */ | ||
1179 | 1212 | ||
1180 | memset(c, 0, sizeof(*c)); | 1213 | mutex_lock(&fdtv->avc_mutex); |
1181 | 1214 | ||
1182 | c->ctype = AVC_CTYPE_STATUS; | 1215 | c->ctype = AVC_CTYPE_STATUS; |
1183 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; | 1216 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; |
@@ -1189,24 +1222,25 @@ int avc_ca_enter_menu(struct firedtv *fdtv) | |||
1189 | c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA; | 1222 | c->operand[3] = SFE_VENDOR_OPCODE_HOST2CA; |
1190 | c->operand[4] = 0; /* slot */ | 1223 | c->operand[4] = 0; /* slot */ |
1191 | c->operand[5] = SFE_VENDOR_TAG_CA_ENTER_MENU; | 1224 | c->operand[5] = SFE_VENDOR_TAG_CA_ENTER_MENU; |
1192 | c->operand[6] = 0; /* more/last */ | 1225 | clear_operands(c, 6, 8); |
1193 | c->operand[7] = 0; /* length */ | ||
1194 | 1226 | ||
1195 | c->length = 12; | 1227 | fdtv->avc_data_length = 12; |
1228 | ret = avc_write(fdtv); | ||
1196 | 1229 | ||
1197 | if (avc_write(fdtv, c, r) < 0) | 1230 | /* FIXME: check response code? */ |
1198 | return -EIO; | ||
1199 | 1231 | ||
1200 | return 0; | 1232 | mutex_unlock(&fdtv->avc_mutex); |
1233 | |||
1234 | return ret; | ||
1201 | } | 1235 | } |
1202 | 1236 | ||
1203 | int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len) | 1237 | int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len) |
1204 | { | 1238 | { |
1205 | char buffer[sizeof(struct avc_command_frame)]; | 1239 | struct avc_command_frame *c = (void *)fdtv->avc_data; |
1206 | struct avc_command_frame *c = (void *)buffer; | 1240 | struct avc_response_frame *r = (void *)fdtv->avc_data; |
1207 | struct avc_response_frame *r = (void *)buffer; | 1241 | int ret; |
1208 | 1242 | ||
1209 | memset(c, 0, sizeof(*c)); | 1243 | mutex_lock(&fdtv->avc_mutex); |
1210 | 1244 | ||
1211 | c->ctype = AVC_CTYPE_STATUS; | 1245 | c->ctype = AVC_CTYPE_STATUS; |
1212 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; | 1246 | c->subunit = AVC_SUBUNIT_TYPE_TUNER | fdtv->subunit; |
@@ -1218,20 +1252,21 @@ int avc_ca_get_mmi(struct firedtv *fdtv, char *mmi_object, unsigned int *len) | |||
1218 | c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST; | 1252 | c->operand[3] = SFE_VENDOR_OPCODE_CA2HOST; |
1219 | c->operand[4] = 0; /* slot */ | 1253 | c->operand[4] = 0; /* slot */ |
1220 | c->operand[5] = SFE_VENDOR_TAG_CA_MMI; | 1254 | c->operand[5] = SFE_VENDOR_TAG_CA_MMI; |
1221 | c->operand[6] = 0; /* more/last */ | 1255 | clear_operands(c, 6, LAST_OPERAND); |
1222 | c->operand[7] = 0; /* length */ | ||
1223 | 1256 | ||
1224 | c->length = 12; | 1257 | fdtv->avc_data_length = 12; |
1225 | 1258 | ret = avc_write(fdtv); | |
1226 | if (avc_write(fdtv, c, r) < 0) | 1259 | if (ret < 0) |
1227 | return -EIO; | 1260 | goto out; |
1228 | 1261 | ||
1229 | /* FIXME: check response code and validate response data */ | 1262 | /* FIXME: check response code and validate response data */ |
1230 | 1263 | ||
1231 | *len = get_ca_object_length(r); | 1264 | *len = get_ca_object_length(r); |
1232 | memcpy(mmi_object, &r->operand[get_ca_object_pos(r)], *len); | 1265 | memcpy(mmi_object, &r->operand[get_ca_object_pos(r)], *len); |
1266 | out: | ||
1267 | mutex_unlock(&fdtv->avc_mutex); | ||
1233 | 1268 | ||
1234 | return 0; | 1269 | return ret; |
1235 | } | 1270 | } |
1236 | 1271 | ||
1237 | #define CMP_OUTPUT_PLUG_CONTROL_REG_0 0xfffff0000904ULL | 1272 | #define CMP_OUTPUT_PLUG_CONTROL_REG_0 0xfffff0000904ULL |
@@ -1240,14 +1275,14 @@ static int cmp_read(struct firedtv *fdtv, u64 addr, __be32 *data) | |||
1240 | { | 1275 | { |
1241 | int ret; | 1276 | int ret; |
1242 | 1277 | ||
1243 | if (mutex_lock_interruptible(&fdtv->avc_mutex)) | 1278 | mutex_lock(&fdtv->avc_mutex); |
1244 | return -EINTR; | ||
1245 | 1279 | ||
1246 | ret = fdtv->backend->read(fdtv, addr, data); | 1280 | ret = fdtv->backend->read(fdtv, addr, data); |
1247 | if (ret < 0) | 1281 | if (ret < 0) |
1248 | dev_err(fdtv->device, "CMP: read I/O error\n"); | 1282 | dev_err(fdtv->device, "CMP: read I/O error\n"); |
1249 | 1283 | ||
1250 | mutex_unlock(&fdtv->avc_mutex); | 1284 | mutex_unlock(&fdtv->avc_mutex); |
1285 | |||
1251 | return ret; | 1286 | return ret; |
1252 | } | 1287 | } |
1253 | 1288 | ||
@@ -1255,14 +1290,19 @@ static int cmp_lock(struct firedtv *fdtv, u64 addr, __be32 data[]) | |||
1255 | { | 1290 | { |
1256 | int ret; | 1291 | int ret; |
1257 | 1292 | ||
1258 | if (mutex_lock_interruptible(&fdtv->avc_mutex)) | 1293 | mutex_lock(&fdtv->avc_mutex); |
1259 | return -EINTR; | 1294 | |
1295 | /* data[] is stack-allocated and should not be DMA-mapped. */ | ||
1296 | memcpy(fdtv->avc_data, data, 8); | ||
1260 | 1297 | ||
1261 | ret = fdtv->backend->lock(fdtv, addr, data); | 1298 | ret = fdtv->backend->lock(fdtv, addr, fdtv->avc_data); |
1262 | if (ret < 0) | 1299 | if (ret < 0) |
1263 | dev_err(fdtv->device, "CMP: lock I/O error\n"); | 1300 | dev_err(fdtv->device, "CMP: lock I/O error\n"); |
1301 | else | ||
1302 | memcpy(data, fdtv->avc_data, 8); | ||
1264 | 1303 | ||
1265 | mutex_unlock(&fdtv->avc_mutex); | 1304 | mutex_unlock(&fdtv->avc_mutex); |
1305 | |||
1266 | return ret; | 1306 | return ret; |
1267 | } | 1307 | } |
1268 | 1308 | ||
diff --git a/drivers/media/dvb/firewire/firedtv-dvb.c b/drivers/media/dvb/firewire/firedtv-dvb.c index fc9996c13e13..079e8c5b0475 100644 --- a/drivers/media/dvb/firewire/firedtv-dvb.c +++ b/drivers/media/dvb/firewire/firedtv-dvb.c | |||
@@ -277,7 +277,6 @@ struct firedtv *fdtv_alloc(struct device *dev, | |||
277 | 277 | ||
278 | mutex_init(&fdtv->avc_mutex); | 278 | mutex_init(&fdtv->avc_mutex); |
279 | init_waitqueue_head(&fdtv->avc_wait); | 279 | init_waitqueue_head(&fdtv->avc_wait); |
280 | fdtv->avc_reply_received = true; | ||
281 | mutex_init(&fdtv->demux_mutex); | 280 | mutex_init(&fdtv->demux_mutex); |
282 | INIT_WORK(&fdtv->remote_ctrl_work, avc_remote_ctrl_work); | 281 | INIT_WORK(&fdtv->remote_ctrl_work, avc_remote_ctrl_work); |
283 | 282 | ||
diff --git a/drivers/media/dvb/firewire/firedtv-fw.c b/drivers/media/dvb/firewire/firedtv-fw.c index 6223bf01efe9..7a3de16fba06 100644 --- a/drivers/media/dvb/firewire/firedtv-fw.c +++ b/drivers/media/dvb/firewire/firedtv-fw.c | |||
@@ -41,7 +41,7 @@ static int node_req(struct firedtv *fdtv, u64 addr, void *data, size_t len, | |||
41 | return rcode != RCODE_COMPLETE ? -EIO : 0; | 41 | return rcode != RCODE_COMPLETE ? -EIO : 0; |
42 | } | 42 | } |
43 | 43 | ||
44 | static int node_lock(struct firedtv *fdtv, u64 addr, __be32 data[]) | 44 | static int node_lock(struct firedtv *fdtv, u64 addr, void *data) |
45 | { | 45 | { |
46 | return node_req(fdtv, addr, data, 8, TCODE_LOCK_COMPARE_SWAP); | 46 | return node_req(fdtv, addr, data, 8, TCODE_LOCK_COMPARE_SWAP); |
47 | } | 47 | } |
diff --git a/drivers/media/dvb/firewire/firedtv.h b/drivers/media/dvb/firewire/firedtv.h index 35080dbb3c66..78cc28f36914 100644 --- a/drivers/media/dvb/firewire/firedtv.h +++ b/drivers/media/dvb/firewire/firedtv.h | |||
@@ -73,7 +73,7 @@ struct input_dev; | |||
73 | struct firedtv; | 73 | struct firedtv; |
74 | 74 | ||
75 | struct firedtv_backend { | 75 | struct firedtv_backend { |
76 | int (*lock)(struct firedtv *fdtv, u64 addr, __be32 data[]); | 76 | int (*lock)(struct firedtv *fdtv, u64 addr, void *data); |
77 | int (*read)(struct firedtv *fdtv, u64 addr, void *data); | 77 | int (*read)(struct firedtv *fdtv, u64 addr, void *data); |
78 | int (*write)(struct firedtv *fdtv, u64 addr, void *data, size_t len); | 78 | int (*write)(struct firedtv *fdtv, u64 addr, void *data, size_t len); |
79 | int (*start_iso)(struct firedtv *fdtv); | 79 | int (*start_iso)(struct firedtv *fdtv); |
@@ -114,8 +114,8 @@ struct firedtv { | |||
114 | unsigned long channel_active; | 114 | unsigned long channel_active; |
115 | u16 channel_pid[16]; | 115 | u16 channel_pid[16]; |
116 | 116 | ||
117 | size_t response_length; | 117 | int avc_data_length; |
118 | u8 response[512]; | 118 | u8 avc_data[512]; |
119 | }; | 119 | }; |
120 | 120 | ||
121 | /* firedtv-1394.c */ | 121 | /* firedtv-1394.c */ |
diff --git a/drivers/media/dvb/frontends/af9013.h b/drivers/media/dvb/frontends/af9013.h index 28b90c91c766..e90fa92b1c1d 100644 --- a/drivers/media/dvb/frontends/af9013.h +++ b/drivers/media/dvb/frontends/af9013.h | |||
@@ -44,6 +44,7 @@ enum af9013_tuner { | |||
44 | AF9013_TUNER_MT2060_2 = 147, /* Microtune */ | 44 | AF9013_TUNER_MT2060_2 = 147, /* Microtune */ |
45 | AF9013_TUNER_TDA18271 = 156, /* NXP */ | 45 | AF9013_TUNER_TDA18271 = 156, /* NXP */ |
46 | AF9013_TUNER_QT1010A = 162, /* Quantek */ | 46 | AF9013_TUNER_QT1010A = 162, /* Quantek */ |
47 | AF9013_TUNER_TDA18218 = 179, /* NXP */ | ||
47 | }; | 48 | }; |
48 | 49 | ||
49 | /* AF9013/5 GPIOs (mostly guessed) | 50 | /* AF9013/5 GPIOs (mostly guessed) |
diff --git a/drivers/media/dvb/frontends/atbm8830.c b/drivers/media/dvb/frontends/atbm8830.c index 59881a5944eb..43aac2f85c2e 100644 --- a/drivers/media/dvb/frontends/atbm8830.c +++ b/drivers/media/dvb/frontends/atbm8830.c | |||
@@ -170,6 +170,19 @@ static int is_locked(struct atbm_state *priv, u8 *locked) | |||
170 | return 0; | 170 | return 0; |
171 | } | 171 | } |
172 | 172 | ||
173 | static int set_agc_config(struct atbm_state *priv, | ||
174 | u8 min, u8 max, u8 hold_loop) | ||
175 | { | ||
176 | /* no effect if both min and max are zero */ | ||
177 | if (!min && !max) | ||
178 | return 0; | ||
179 | |||
180 | atbm8830_write_reg(priv, REG_AGC_MIN, min); | ||
181 | atbm8830_write_reg(priv, REG_AGC_MAX, max); | ||
182 | atbm8830_write_reg(priv, REG_AGC_HOLD_LOOP, hold_loop); | ||
183 | |||
184 | return 0; | ||
185 | } | ||
173 | 186 | ||
174 | static int set_static_channel_mode(struct atbm_state *priv) | 187 | static int set_static_channel_mode(struct atbm_state *priv) |
175 | { | 188 | { |
@@ -227,6 +240,9 @@ static int atbm8830_init(struct dvb_frontend *fe) | |||
227 | /*Set IF frequency*/ | 240 | /*Set IF frequency*/ |
228 | set_if_freq(priv, cfg->if_freq); | 241 | set_if_freq(priv, cfg->if_freq); |
229 | 242 | ||
243 | /*Set AGC Config*/ | ||
244 | set_agc_config(priv, cfg->agc_min, cfg->agc_max, | ||
245 | cfg->agc_hold_loop); | ||
230 | 246 | ||
231 | /*Set static channel mode*/ | 247 | /*Set static channel mode*/ |
232 | set_static_channel_mode(priv); | 248 | set_static_channel_mode(priv); |
diff --git a/drivers/media/dvb/frontends/dib0090.c b/drivers/media/dvb/frontends/dib0090.c index 614552709a6f..7eac178f57b2 100644 --- a/drivers/media/dvb/frontends/dib0090.c +++ b/drivers/media/dvb/frontends/dib0090.c | |||
@@ -283,7 +283,7 @@ static int dib0090_sleep(struct dvb_frontend *fe) | |||
283 | return 0; | 283 | return 0; |
284 | } | 284 | } |
285 | 285 | ||
286 | extern void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast) | 286 | void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast) |
287 | { | 287 | { |
288 | struct dib0090_state *state = fe->tuner_priv; | 288 | struct dib0090_state *state = fe->tuner_priv; |
289 | if (fast) | 289 | if (fast) |
diff --git a/drivers/media/dvb/frontends/dib8000.c b/drivers/media/dvb/frontends/dib8000.c index 6f6fa29d9ea4..2aa97dd6a8af 100644 --- a/drivers/media/dvb/frontends/dib8000.c +++ b/drivers/media/dvb/frontends/dib8000.c | |||
@@ -1999,6 +1999,8 @@ static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_par | |||
1999 | struct dib8000_state *state = fe->demodulator_priv; | 1999 | struct dib8000_state *state = fe->demodulator_priv; |
2000 | int time, ret; | 2000 | int time, ret; |
2001 | 2001 | ||
2002 | fe->dtv_property_cache.delivery_system = SYS_ISDBT; | ||
2003 | |||
2002 | dib8000_set_output_mode(state, OUTMODE_HIGH_Z); | 2004 | dib8000_set_output_mode(state, OUTMODE_HIGH_Z); |
2003 | 2005 | ||
2004 | if (fe->ops.tuner_ops.set_params) | 2006 | if (fe->ops.tuner_ops.set_params) |
diff --git a/drivers/media/dvb/frontends/dibx000_common.c b/drivers/media/dvb/frontends/dibx000_common.c index e6f3d73db9d3..980e02f1575e 100644 --- a/drivers/media/dvb/frontends/dibx000_common.c +++ b/drivers/media/dvb/frontends/dibx000_common.c | |||
@@ -174,7 +174,7 @@ void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst) | |||
174 | EXPORT_SYMBOL(dibx000_exit_i2c_master); | 174 | EXPORT_SYMBOL(dibx000_exit_i2c_master); |
175 | 175 | ||
176 | 176 | ||
177 | u32 systime() | 177 | u32 systime(void) |
178 | { | 178 | { |
179 | struct timespec t; | 179 | struct timespec t; |
180 | 180 | ||
diff --git a/drivers/media/dvb/frontends/l64781.c b/drivers/media/dvb/frontends/l64781.c index 3051b64aa17c..445fa1068064 100644 --- a/drivers/media/dvb/frontends/l64781.c +++ b/drivers/media/dvb/frontends/l64781.c | |||
@@ -192,8 +192,8 @@ static int apply_frontend_param (struct dvb_frontend* fe, struct dvb_frontend_pa | |||
192 | spi_bias *= qam_tab[p->constellation]; | 192 | spi_bias *= qam_tab[p->constellation]; |
193 | spi_bias /= p->code_rate_HP + 1; | 193 | spi_bias /= p->code_rate_HP + 1; |
194 | spi_bias /= (guard_tab[p->guard_interval] + 32); | 194 | spi_bias /= (guard_tab[p->guard_interval] + 32); |
195 | spi_bias *= 1000ULL; | 195 | spi_bias *= 1000; |
196 | spi_bias /= 1000ULL + ppm/1000; | 196 | spi_bias /= 1000 + ppm/1000; |
197 | spi_bias *= p->code_rate_HP; | 197 | spi_bias *= p->code_rate_HP; |
198 | 198 | ||
199 | val0x04 = (p->transmission_mode << 2) | p->guard_interval; | 199 | val0x04 = (p->transmission_mode << 2) | p->guard_interval; |
diff --git a/drivers/media/dvb/frontends/lnbp21.c b/drivers/media/dvb/frontends/lnbp21.c index b181bf023ada..13437259eeac 100644 --- a/drivers/media/dvb/frontends/lnbp21.c +++ b/drivers/media/dvb/frontends/lnbp21.c | |||
@@ -158,7 +158,8 @@ static struct dvb_frontend *lnbx2x_attach(struct dvb_frontend *fe, | |||
158 | /* override frontend ops */ | 158 | /* override frontend ops */ |
159 | fe->ops.set_voltage = lnbp21_set_voltage; | 159 | fe->ops.set_voltage = lnbp21_set_voltage; |
160 | fe->ops.enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; | 160 | fe->ops.enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; |
161 | fe->ops.set_tone = lnbp21_set_tone; | 161 | if (!(override_clear & LNBH24_TEN)) /*22kHz logic controlled by demod*/ |
162 | fe->ops.set_tone = lnbp21_set_tone; | ||
162 | printk(KERN_INFO "LNBx2x attached on addr=%x\n", lnbp21->i2c_addr); | 163 | printk(KERN_INFO "LNBx2x attached on addr=%x\n", lnbp21->i2c_addr); |
163 | 164 | ||
164 | return fe; | 165 | return fe; |
diff --git a/drivers/media/dvb/frontends/si21xx.c b/drivers/media/dvb/frontends/si21xx.c index 9552a22ccffb..d21a327db629 100644 --- a/drivers/media/dvb/frontends/si21xx.c +++ b/drivers/media/dvb/frontends/si21xx.c | |||
@@ -97,8 +97,6 @@ | |||
97 | #define LNB_SUPPLY_CTRL_REG_4 0xce | 97 | #define LNB_SUPPLY_CTRL_REG_4 0xce |
98 | #define LNB_SUPPLY_STATUS_REG 0xcf | 98 | #define LNB_SUPPLY_STATUS_REG 0xcf |
99 | 99 | ||
100 | #define FALSE 0 | ||
101 | #define TRUE 1 | ||
102 | #define FAIL -1 | 100 | #define FAIL -1 |
103 | #define PASS 0 | 101 | #define PASS 0 |
104 | 102 | ||
@@ -718,7 +716,7 @@ static int si21xx_set_frontend(struct dvb_frontend *fe, | |||
718 | int fine_tune_freq; | 716 | int fine_tune_freq; |
719 | unsigned char sample_rate = 0; | 717 | unsigned char sample_rate = 0; |
720 | /* boolean */ | 718 | /* boolean */ |
721 | unsigned int inband_interferer_ind; | 719 | bool inband_interferer_ind; |
722 | 720 | ||
723 | /* INTERMEDIATE VALUES */ | 721 | /* INTERMEDIATE VALUES */ |
724 | int icoarse_tune_freq; /* MHz */ | 722 | int icoarse_tune_freq; /* MHz */ |
@@ -728,15 +726,8 @@ static int si21xx_set_frontend(struct dvb_frontend *fe, | |||
728 | unsigned int x1; | 726 | unsigned int x1; |
729 | unsigned int x2; | 727 | unsigned int x2; |
730 | int i; | 728 | int i; |
731 | unsigned int inband_interferer_div2[ALLOWABLE_FS_COUNT] = { | 729 | bool inband_interferer_div2[ALLOWABLE_FS_COUNT]; |
732 | FALSE, FALSE, FALSE, FALSE, FALSE, | 730 | bool inband_interferer_div4[ALLOWABLE_FS_COUNT]; |
733 | FALSE, FALSE, FALSE, FALSE, FALSE | ||
734 | }; | ||
735 | unsigned int inband_interferer_div4[ALLOWABLE_FS_COUNT] = { | ||
736 | FALSE, FALSE, FALSE, FALSE, FALSE, | ||
737 | FALSE, FALSE, FALSE, FALSE, FALSE | ||
738 | }; | ||
739 | |||
740 | int status; | 731 | int status; |
741 | 732 | ||
742 | /* allowable sample rates for ADC in MHz */ | 733 | /* allowable sample rates for ADC in MHz */ |
@@ -762,7 +753,7 @@ static int si21xx_set_frontend(struct dvb_frontend *fe, | |||
762 | } | 753 | } |
763 | 754 | ||
764 | for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) | 755 | for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) |
765 | inband_interferer_div2[i] = inband_interferer_div4[i] = FALSE; | 756 | inband_interferer_div2[i] = inband_interferer_div4[i] = false; |
766 | 757 | ||
767 | if_limit_high = -700000; | 758 | if_limit_high = -700000; |
768 | if_limit_low = -100000; | 759 | if_limit_low = -100000; |
@@ -798,7 +789,7 @@ static int si21xx_set_frontend(struct dvb_frontend *fe, | |||
798 | 789 | ||
799 | if (((band_low < x1) && (x1 < band_high)) || | 790 | if (((band_low < x1) && (x1 < band_high)) || |
800 | ((band_low < x2) && (x2 < band_high))) | 791 | ((band_low < x2) && (x2 < band_high))) |
801 | inband_interferer_div4[i] = TRUE; | 792 | inband_interferer_div4[i] = true; |
802 | 793 | ||
803 | } | 794 | } |
804 | 795 | ||
@@ -811,25 +802,28 @@ static int si21xx_set_frontend(struct dvb_frontend *fe, | |||
811 | 802 | ||
812 | if (((band_low < x1) && (x1 < band_high)) || | 803 | if (((band_low < x1) && (x1 < band_high)) || |
813 | ((band_low < x2) && (x2 < band_high))) | 804 | ((band_low < x2) && (x2 < band_high))) |
814 | inband_interferer_div2[i] = TRUE; | 805 | inband_interferer_div2[i] = true; |
815 | } | 806 | } |
816 | 807 | ||
817 | inband_interferer_ind = TRUE; | 808 | inband_interferer_ind = true; |
818 | for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) | 809 | for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) { |
819 | inband_interferer_ind &= inband_interferer_div2[i] | | 810 | if (inband_interferer_div2[i] || inband_interferer_div4[i]) { |
820 | inband_interferer_div4[i]; | 811 | inband_interferer_ind = false; |
812 | break; | ||
813 | } | ||
814 | } | ||
821 | 815 | ||
822 | if (inband_interferer_ind) { | 816 | if (inband_interferer_ind) { |
823 | for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) { | 817 | for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) { |
824 | if (inband_interferer_div2[i] == FALSE) { | 818 | if (!inband_interferer_div2[i]) { |
825 | sample_rate = (u8) afs[i]; | 819 | sample_rate = (u8) afs[i]; |
826 | break; | 820 | break; |
827 | } | 821 | } |
828 | } | 822 | } |
829 | } else { | 823 | } else { |
830 | for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) { | 824 | for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) { |
831 | if ((inband_interferer_div2[i] | | 825 | if ((inband_interferer_div2[i] || |
832 | inband_interferer_div4[i]) == FALSE) { | 826 | !inband_interferer_div4[i])) { |
833 | sample_rate = (u8) afs[i]; | 827 | sample_rate = (u8) afs[i]; |
834 | break; | 828 | break; |
835 | } | 829 | } |
diff --git a/drivers/media/dvb/frontends/stv0900.h b/drivers/media/dvb/frontends/stv0900.h index 29c3fa85c227..e3e35d1ce838 100644 --- a/drivers/media/dvb/frontends/stv0900.h +++ b/drivers/media/dvb/frontends/stv0900.h | |||
@@ -49,6 +49,8 @@ struct stv0900_config { | |||
49 | u8 tun2_maddress; | 49 | u8 tun2_maddress; |
50 | u8 tun1_adc;/* 1 for stv6110, 2 for stb6100 */ | 50 | u8 tun1_adc;/* 1 for stv6110, 2 for stb6100 */ |
51 | u8 tun2_adc; | 51 | u8 tun2_adc; |
52 | u8 tun1_type;/* for now 3 for stb6100 auto, else - software */ | ||
53 | u8 tun2_type; | ||
52 | /* Set device param to start dma */ | 54 | /* Set device param to start dma */ |
53 | int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured); | 55 | int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured); |
54 | }; | 56 | }; |
diff --git a/drivers/media/dvb/frontends/stv0900_core.c b/drivers/media/dvb/frontends/stv0900_core.c index 8762c86044a5..01f8f1f802fd 100644 --- a/drivers/media/dvb/frontends/stv0900_core.c +++ b/drivers/media/dvb/frontends/stv0900_core.c | |||
@@ -177,7 +177,7 @@ u8 stv0900_read_reg(struct stv0900_internal *intp, u16 reg) | |||
177 | return buf; | 177 | return buf; |
178 | } | 178 | } |
179 | 179 | ||
180 | void extract_mask_pos(u32 label, u8 *mask, u8 *pos) | 180 | static void extract_mask_pos(u32 label, u8 *mask, u8 *pos) |
181 | { | 181 | { |
182 | u8 position = 0, i = 0; | 182 | u8 position = 0, i = 0; |
183 | 183 | ||
@@ -218,7 +218,7 @@ u8 stv0900_get_bits(struct stv0900_internal *intp, u32 label) | |||
218 | return val; | 218 | return val; |
219 | } | 219 | } |
220 | 220 | ||
221 | enum fe_stv0900_error stv0900_initialize(struct stv0900_internal *intp) | 221 | static enum fe_stv0900_error stv0900_initialize(struct stv0900_internal *intp) |
222 | { | 222 | { |
223 | s32 i; | 223 | s32 i; |
224 | 224 | ||
@@ -282,7 +282,7 @@ enum fe_stv0900_error stv0900_initialize(struct stv0900_internal *intp) | |||
282 | return STV0900_NO_ERROR; | 282 | return STV0900_NO_ERROR; |
283 | } | 283 | } |
284 | 284 | ||
285 | u32 stv0900_get_mclk_freq(struct stv0900_internal *intp, u32 ext_clk) | 285 | static u32 stv0900_get_mclk_freq(struct stv0900_internal *intp, u32 ext_clk) |
286 | { | 286 | { |
287 | u32 mclk = 90000000, div = 0, ad_div = 0; | 287 | u32 mclk = 90000000, div = 0, ad_div = 0; |
288 | 288 | ||
@@ -296,7 +296,7 @@ u32 stv0900_get_mclk_freq(struct stv0900_internal *intp, u32 ext_clk) | |||
296 | return mclk; | 296 | return mclk; |
297 | } | 297 | } |
298 | 298 | ||
299 | enum fe_stv0900_error stv0900_set_mclk(struct stv0900_internal *intp, u32 mclk) | 299 | static enum fe_stv0900_error stv0900_set_mclk(struct stv0900_internal *intp, u32 mclk) |
300 | { | 300 | { |
301 | u32 m_div, clk_sel; | 301 | u32 m_div, clk_sel; |
302 | 302 | ||
@@ -334,7 +334,7 @@ enum fe_stv0900_error stv0900_set_mclk(struct stv0900_internal *intp, u32 mclk) | |||
334 | return STV0900_NO_ERROR; | 334 | return STV0900_NO_ERROR; |
335 | } | 335 | } |
336 | 336 | ||
337 | u32 stv0900_get_err_count(struct stv0900_internal *intp, int cntr, | 337 | static u32 stv0900_get_err_count(struct stv0900_internal *intp, int cntr, |
338 | enum fe_stv0900_demod_num demod) | 338 | enum fe_stv0900_demod_num demod) |
339 | { | 339 | { |
340 | u32 lsb, msb, hsb, err_val; | 340 | u32 lsb, msb, hsb, err_val; |
@@ -567,6 +567,46 @@ void stv0900_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth) | |||
567 | } | 567 | } |
568 | } | 568 | } |
569 | 569 | ||
570 | u32 stv0900_get_freq_auto(struct stv0900_internal *intp, int demod) | ||
571 | { | ||
572 | u32 freq, round; | ||
573 | /* Formulat : | ||
574 | Tuner_Frequency(MHz) = Regs / 64 | ||
575 | Tuner_granularity(MHz) = Regs / 2048 | ||
576 | real_Tuner_Frequency = Tuner_Frequency(MHz) - Tuner_granularity(MHz) | ||
577 | */ | ||
578 | freq = (stv0900_get_bits(intp, TUN_RFFREQ2) << 10) + | ||
579 | (stv0900_get_bits(intp, TUN_RFFREQ1) << 2) + | ||
580 | stv0900_get_bits(intp, TUN_RFFREQ0); | ||
581 | |||
582 | freq = (freq * 1000) / 64; | ||
583 | |||
584 | round = (stv0900_get_bits(intp, TUN_RFRESTE1) >> 2) + | ||
585 | stv0900_get_bits(intp, TUN_RFRESTE0); | ||
586 | |||
587 | round = (round * 1000) / 2048; | ||
588 | |||
589 | return freq + round; | ||
590 | } | ||
591 | |||
592 | void stv0900_set_tuner_auto(struct stv0900_internal *intp, u32 Frequency, | ||
593 | u32 Bandwidth, int demod) | ||
594 | { | ||
595 | u32 tunerFrequency; | ||
596 | /* Formulat: | ||
597 | Tuner_frequency_reg= Frequency(MHz)*64 | ||
598 | */ | ||
599 | tunerFrequency = (Frequency * 64) / 1000; | ||
600 | |||
601 | stv0900_write_bits(intp, TUN_RFFREQ2, (tunerFrequency >> 10)); | ||
602 | stv0900_write_bits(intp, TUN_RFFREQ1, (tunerFrequency >> 2) & 0xff); | ||
603 | stv0900_write_bits(intp, TUN_RFFREQ0, (tunerFrequency & 0x03)); | ||
604 | /* Low Pass Filter = BW /2 (MHz)*/ | ||
605 | stv0900_write_bits(intp, TUN_BW, Bandwidth / 2000000); | ||
606 | /* Tuner Write trig */ | ||
607 | stv0900_write_reg(intp, TNRLD, 1); | ||
608 | } | ||
609 | |||
570 | static s32 stv0900_get_rf_level(struct stv0900_internal *intp, | 610 | static s32 stv0900_get_rf_level(struct stv0900_internal *intp, |
571 | const struct stv0900_table *lookup, | 611 | const struct stv0900_table *lookup, |
572 | enum fe_stv0900_demod_num demod) | 612 | enum fe_stv0900_demod_num demod) |
@@ -1329,7 +1369,6 @@ static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe, | |||
1329 | enum fe_stv0900_error error = STV0900_NO_ERROR; | 1369 | enum fe_stv0900_error error = STV0900_NO_ERROR; |
1330 | enum fe_stv0900_error demodError = STV0900_NO_ERROR; | 1370 | enum fe_stv0900_error demodError = STV0900_NO_ERROR; |
1331 | struct stv0900_internal *intp = NULL; | 1371 | struct stv0900_internal *intp = NULL; |
1332 | |||
1333 | int selosci, i; | 1372 | int selosci, i; |
1334 | 1373 | ||
1335 | struct stv0900_inode *temp_int = find_inode(state->i2c_adap, | 1374 | struct stv0900_inode *temp_int = find_inode(state->i2c_adap, |
@@ -1345,7 +1384,14 @@ static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe, | |||
1345 | } else { | 1384 | } else { |
1346 | state->internal = kmalloc(sizeof(struct stv0900_internal), | 1385 | state->internal = kmalloc(sizeof(struct stv0900_internal), |
1347 | GFP_KERNEL); | 1386 | GFP_KERNEL); |
1387 | if (state->internal == NULL) | ||
1388 | return STV0900_INVALID_HANDLE; | ||
1348 | temp_int = append_internal(state->internal); | 1389 | temp_int = append_internal(state->internal); |
1390 | if (temp_int == NULL) { | ||
1391 | kfree(state->internal); | ||
1392 | state->internal = NULL; | ||
1393 | return STV0900_INVALID_HANDLE; | ||
1394 | } | ||
1349 | state->internal->dmds_used = 1; | 1395 | state->internal->dmds_used = 1; |
1350 | state->internal->i2c_adap = state->i2c_adap; | 1396 | state->internal->i2c_adap = state->i2c_adap; |
1351 | state->internal->i2c_addr = state->config->demod_address; | 1397 | state->internal->i2c_addr = state->config->demod_address; |
@@ -1371,11 +1417,6 @@ static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe, | |||
1371 | return error; | 1417 | return error; |
1372 | } | 1418 | } |
1373 | 1419 | ||
1374 | if (state->internal == NULL) { | ||
1375 | error = STV0900_INVALID_HANDLE; | ||
1376 | return error; | ||
1377 | } | ||
1378 | |||
1379 | intp = state->internal; | 1420 | intp = state->internal; |
1380 | 1421 | ||
1381 | intp->demod_mode = p_init->demod_mode; | 1422 | intp->demod_mode = p_init->demod_mode; |
@@ -1404,6 +1445,27 @@ static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe, | |||
1404 | stv0900_write_bits(intp, F0900_P1_RST_HWARE, 0); | 1445 | stv0900_write_bits(intp, F0900_P1_RST_HWARE, 0); |
1405 | } | 1446 | } |
1406 | 1447 | ||
1448 | intp->tuner_type[0] = p_init->tuner1_type; | ||
1449 | intp->tuner_type[1] = p_init->tuner2_type; | ||
1450 | /* tuner init */ | ||
1451 | switch (p_init->tuner1_type) { | ||
1452 | case 3: /*FE_AUTO_STB6100:*/ | ||
1453 | stv0900_write_reg(intp, R0900_P1_TNRCFG, 0x3c); | ||
1454 | stv0900_write_reg(intp, R0900_P1_TNRCFG2, 0x86); | ||
1455 | stv0900_write_reg(intp, R0900_P1_TNRCFG3, 0x18); | ||
1456 | stv0900_write_reg(intp, R0900_P1_TNRXTAL, 27); /* 27MHz */ | ||
1457 | stv0900_write_reg(intp, R0900_P1_TNRSTEPS, 0x05); | ||
1458 | stv0900_write_reg(intp, R0900_P1_TNRGAIN, 0x17); | ||
1459 | stv0900_write_reg(intp, R0900_P1_TNRADJ, 0x1f); | ||
1460 | stv0900_write_reg(intp, R0900_P1_TNRCTL2, 0x0); | ||
1461 | stv0900_write_bits(intp, F0900_P1_TUN_TYPE, 3); | ||
1462 | break; | ||
1463 | /* case FE_SW_TUNER: */ | ||
1464 | default: | ||
1465 | stv0900_write_bits(intp, F0900_P1_TUN_TYPE, 6); | ||
1466 | break; | ||
1467 | } | ||
1468 | |||
1407 | stv0900_write_bits(intp, F0900_P1_TUN_MADDRESS, p_init->tun1_maddress); | 1469 | stv0900_write_bits(intp, F0900_P1_TUN_MADDRESS, p_init->tun1_maddress); |
1408 | switch (p_init->tuner1_adc) { | 1470 | switch (p_init->tuner1_adc) { |
1409 | case 1: | 1471 | case 1: |
@@ -1413,6 +1475,27 @@ static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe, | |||
1413 | break; | 1475 | break; |
1414 | } | 1476 | } |
1415 | 1477 | ||
1478 | stv0900_write_reg(intp, R0900_P1_TNRLD, 1); /* hw tuner */ | ||
1479 | |||
1480 | /* tuner init */ | ||
1481 | switch (p_init->tuner2_type) { | ||
1482 | case 3: /*FE_AUTO_STB6100:*/ | ||
1483 | stv0900_write_reg(intp, R0900_P2_TNRCFG, 0x3c); | ||
1484 | stv0900_write_reg(intp, R0900_P2_TNRCFG2, 0x86); | ||
1485 | stv0900_write_reg(intp, R0900_P2_TNRCFG3, 0x18); | ||
1486 | stv0900_write_reg(intp, R0900_P2_TNRXTAL, 27); /* 27MHz */ | ||
1487 | stv0900_write_reg(intp, R0900_P2_TNRSTEPS, 0x05); | ||
1488 | stv0900_write_reg(intp, R0900_P2_TNRGAIN, 0x17); | ||
1489 | stv0900_write_reg(intp, R0900_P2_TNRADJ, 0x1f); | ||
1490 | stv0900_write_reg(intp, R0900_P2_TNRCTL2, 0x0); | ||
1491 | stv0900_write_bits(intp, F0900_P2_TUN_TYPE, 3); | ||
1492 | break; | ||
1493 | /* case FE_SW_TUNER: */ | ||
1494 | default: | ||
1495 | stv0900_write_bits(intp, F0900_P2_TUN_TYPE, 6); | ||
1496 | break; | ||
1497 | } | ||
1498 | |||
1416 | stv0900_write_bits(intp, F0900_P2_TUN_MADDRESS, p_init->tun2_maddress); | 1499 | stv0900_write_bits(intp, F0900_P2_TUN_MADDRESS, p_init->tun2_maddress); |
1417 | switch (p_init->tuner2_adc) { | 1500 | switch (p_init->tuner2_adc) { |
1418 | case 1: | 1501 | case 1: |
@@ -1422,6 +1505,8 @@ static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe, | |||
1422 | break; | 1505 | break; |
1423 | } | 1506 | } |
1424 | 1507 | ||
1508 | stv0900_write_reg(intp, R0900_P2_TNRLD, 1); /* hw tuner */ | ||
1509 | |||
1425 | stv0900_write_bits(intp, F0900_P1_TUN_IQSWAP, p_init->tun1_iq_inv); | 1510 | stv0900_write_bits(intp, F0900_P1_TUN_IQSWAP, p_init->tun1_iq_inv); |
1426 | stv0900_write_bits(intp, F0900_P2_TUN_IQSWAP, p_init->tun2_iq_inv); | 1511 | stv0900_write_bits(intp, F0900_P2_TUN_IQSWAP, p_init->tun2_iq_inv); |
1427 | stv0900_set_mclk(intp, 135000000); | 1512 | stv0900_set_mclk(intp, 135000000); |
@@ -1824,10 +1909,12 @@ struct dvb_frontend *stv0900_attach(const struct stv0900_config *config, | |||
1824 | init_params.tun1_maddress = config->tun1_maddress; | 1909 | init_params.tun1_maddress = config->tun1_maddress; |
1825 | init_params.tun1_iq_inv = STV0900_IQ_NORMAL; | 1910 | init_params.tun1_iq_inv = STV0900_IQ_NORMAL; |
1826 | init_params.tuner1_adc = config->tun1_adc; | 1911 | init_params.tuner1_adc = config->tun1_adc; |
1912 | init_params.tuner1_type = config->tun1_type; | ||
1827 | init_params.path2_ts_clock = config->path2_mode; | 1913 | init_params.path2_ts_clock = config->path2_mode; |
1828 | init_params.ts_config = config->ts_config_regs; | 1914 | init_params.ts_config = config->ts_config_regs; |
1829 | init_params.tun2_maddress = config->tun2_maddress; | 1915 | init_params.tun2_maddress = config->tun2_maddress; |
1830 | init_params.tuner2_adc = config->tun2_adc; | 1916 | init_params.tuner2_adc = config->tun2_adc; |
1917 | init_params.tuner2_type = config->tun2_type; | ||
1831 | init_params.tun2_iq_inv = STV0900_IQ_SWAPPED; | 1918 | init_params.tun2_iq_inv = STV0900_IQ_SWAPPED; |
1832 | 1919 | ||
1833 | err_stv0900 = stv0900_init_internal(&state->frontend, | 1920 | err_stv0900 = stv0900_init_internal(&state->frontend, |
diff --git a/drivers/media/dvb/frontends/stv0900_priv.h b/drivers/media/dvb/frontends/stv0900_priv.h index d8ba8a984abe..b62b0f0a4fef 100644 --- a/drivers/media/dvb/frontends/stv0900_priv.h +++ b/drivers/media/dvb/frontends/stv0900_priv.h | |||
@@ -247,6 +247,7 @@ struct stv0900_init_params{ | |||
247 | 247 | ||
248 | u8 tun1_maddress; | 248 | u8 tun1_maddress; |
249 | int tuner1_adc; | 249 | int tuner1_adc; |
250 | int tuner1_type; | ||
250 | 251 | ||
251 | /* IQ from the tuner1 to the demod */ | 252 | /* IQ from the tuner1 to the demod */ |
252 | enum stv0900_iq_inversion tun1_iq_inv; | 253 | enum stv0900_iq_inversion tun1_iq_inv; |
@@ -254,6 +255,7 @@ struct stv0900_init_params{ | |||
254 | 255 | ||
255 | u8 tun2_maddress; | 256 | u8 tun2_maddress; |
256 | int tuner2_adc; | 257 | int tuner2_adc; |
258 | int tuner2_type; | ||
257 | 259 | ||
258 | /* IQ from the tuner2 to the demod */ | 260 | /* IQ from the tuner2 to the demod */ |
259 | enum stv0900_iq_inversion tun2_iq_inv; | 261 | enum stv0900_iq_inversion tun2_iq_inv; |
@@ -309,6 +311,8 @@ struct stv0900_internal{ | |||
309 | s32 bw[2]; | 311 | s32 bw[2]; |
310 | s32 symbol_rate[2]; | 312 | s32 symbol_rate[2]; |
311 | s32 srch_range[2]; | 313 | s32 srch_range[2]; |
314 | /* for software/auto tuner */ | ||
315 | int tuner_type[2]; | ||
312 | 316 | ||
313 | /* algorithm for search Blind, Cold or Warm*/ | 317 | /* algorithm for search Blind, Cold or Warm*/ |
314 | enum fe_stv0900_search_algo srch_algo[2]; | 318 | enum fe_stv0900_search_algo srch_algo[2]; |
@@ -394,4 +398,11 @@ extern enum | |||
394 | fe_stv0900_tracking_standard stv0900_get_standard(struct dvb_frontend *fe, | 398 | fe_stv0900_tracking_standard stv0900_get_standard(struct dvb_frontend *fe, |
395 | enum fe_stv0900_demod_num demod); | 399 | enum fe_stv0900_demod_num demod); |
396 | 400 | ||
401 | extern u32 | ||
402 | stv0900_get_freq_auto(struct stv0900_internal *intp, int demod); | ||
403 | |||
404 | extern void | ||
405 | stv0900_set_tuner_auto(struct stv0900_internal *intp, u32 Frequency, | ||
406 | u32 Bandwidth, int demod); | ||
407 | |||
397 | #endif | 408 | #endif |
diff --git a/drivers/media/dvb/frontends/stv0900_reg.h b/drivers/media/dvb/frontends/stv0900_reg.h index 7b8edf192e97..731afe93a823 100644 --- a/drivers/media/dvb/frontends/stv0900_reg.h +++ b/drivers/media/dvb/frontends/stv0900_reg.h | |||
@@ -3174,17 +3174,21 @@ extern s32 shiftx(s32 x, int demod, s32 shift); | |||
3174 | #define R0900_P1_TNRRF1 0xf4e9 | 3174 | #define R0900_P1_TNRRF1 0xf4e9 |
3175 | #define TNRRF1 REGx(R0900_P1_TNRRF1) | 3175 | #define TNRRF1 REGx(R0900_P1_TNRRF1) |
3176 | #define F0900_P1_TUN_RFFREQ2 0xf4e900ff | 3176 | #define F0900_P1_TUN_RFFREQ2 0xf4e900ff |
3177 | #define TUN_RFFREQ2 FLDx(F0900_P1_TUN_RFFREQ2) | ||
3177 | 3178 | ||
3178 | /*P1_TNRRF0*/ | 3179 | /*P1_TNRRF0*/ |
3179 | #define R0900_P1_TNRRF0 0xf4ea | 3180 | #define R0900_P1_TNRRF0 0xf4ea |
3180 | #define TNRRF0 REGx(R0900_P1_TNRRF0) | 3181 | #define TNRRF0 REGx(R0900_P1_TNRRF0) |
3181 | #define F0900_P1_TUN_RFFREQ1 0xf4ea00ff | 3182 | #define F0900_P1_TUN_RFFREQ1 0xf4ea00ff |
3183 | #define TUN_RFFREQ1 FLDx(F0900_P1_TUN_RFFREQ1) | ||
3182 | 3184 | ||
3183 | /*P1_TNRBW*/ | 3185 | /*P1_TNRBW*/ |
3184 | #define R0900_P1_TNRBW 0xf4eb | 3186 | #define R0900_P1_TNRBW 0xf4eb |
3185 | #define TNRBW REGx(R0900_P1_TNRBW) | 3187 | #define TNRBW REGx(R0900_P1_TNRBW) |
3186 | #define F0900_P1_TUN_RFFREQ0 0xf4eb00c0 | 3188 | #define F0900_P1_TUN_RFFREQ0 0xf4eb00c0 |
3189 | #define TUN_RFFREQ0 FLDx(F0900_P1_TUN_RFFREQ0) | ||
3187 | #define F0900_P1_TUN_BW 0xf4eb003f | 3190 | #define F0900_P1_TUN_BW 0xf4eb003f |
3191 | #define TUN_BW FLDx(F0900_P1_TUN_BW) | ||
3188 | 3192 | ||
3189 | /*P1_TNRADJ*/ | 3193 | /*P1_TNRADJ*/ |
3190 | #define R0900_P1_TNRADJ 0xf4ec | 3194 | #define R0900_P1_TNRADJ 0xf4ec |
@@ -3234,11 +3238,13 @@ extern s32 shiftx(s32 x, int demod, s32 shift); | |||
3234 | #define F0900_P1_TUN_I2CLOCKED 0xf4f60010 | 3238 | #define F0900_P1_TUN_I2CLOCKED 0xf4f60010 |
3235 | #define F0900_P1_TUN_PROGDONE 0xf4f6000c | 3239 | #define F0900_P1_TUN_PROGDONE 0xf4f6000c |
3236 | #define F0900_P1_TUN_RFRESTE1 0xf4f60003 | 3240 | #define F0900_P1_TUN_RFRESTE1 0xf4f60003 |
3241 | #define TUN_RFRESTE1 FLDx(F0900_P1_TUN_RFRESTE1) | ||
3237 | 3242 | ||
3238 | /*P1_TNRRESTE*/ | 3243 | /*P1_TNRRESTE*/ |
3239 | #define R0900_P1_TNRRESTE 0xf4f7 | 3244 | #define R0900_P1_TNRRESTE 0xf4f7 |
3240 | #define TNRRESTE REGx(R0900_P1_TNRRESTE) | 3245 | #define TNRRESTE REGx(R0900_P1_TNRRESTE) |
3241 | #define F0900_P1_TUN_RFRESTE0 0xf4f700ff | 3246 | #define F0900_P1_TUN_RFRESTE0 0xf4f700ff |
3247 | #define TUN_RFRESTE0 FLDx(F0900_P1_TUN_RFRESTE0) | ||
3242 | 3248 | ||
3243 | /*P1_SMAPCOEF7*/ | 3249 | /*P1_SMAPCOEF7*/ |
3244 | #define R0900_P1_SMAPCOEF7 0xf500 | 3250 | #define R0900_P1_SMAPCOEF7 0xf500 |
diff --git a/drivers/media/dvb/frontends/stv0900_sw.c b/drivers/media/dvb/frontends/stv0900_sw.c index b8da87fa637f..ba0709b2d433 100644 --- a/drivers/media/dvb/frontends/stv0900_sw.c +++ b/drivers/media/dvb/frontends/stv0900_sw.c | |||
@@ -193,7 +193,7 @@ static int stv0900_search_carr_sw_loop(struct stv0900_internal *intp, | |||
193 | return lock; | 193 | return lock; |
194 | } | 194 | } |
195 | 195 | ||
196 | int stv0900_sw_algo(struct stv0900_internal *intp, | 196 | static int stv0900_sw_algo(struct stv0900_internal *intp, |
197 | enum fe_stv0900_demod_num demod) | 197 | enum fe_stv0900_demod_num demod) |
198 | { | 198 | { |
199 | int lock = FALSE, | 199 | int lock = FALSE, |
@@ -606,7 +606,12 @@ static int stv0900_get_demod_cold_lock(struct dvb_frontend *fe, | |||
606 | tuner_freq -= (current_step * currier_step); | 606 | tuner_freq -= (current_step * currier_step); |
607 | 607 | ||
608 | if (intp->chip_id <= 0x20) { | 608 | if (intp->chip_id <= 0x20) { |
609 | stv0900_set_tuner(fe, tuner_freq, intp->bw[d]); | 609 | if (intp->tuner_type[d] == 3) |
610 | stv0900_set_tuner_auto(intp, tuner_freq, | ||
611 | intp->bw[d], demod); | ||
612 | else | ||
613 | stv0900_set_tuner(fe, tuner_freq, intp->bw[d]); | ||
614 | |||
610 | stv0900_write_reg(intp, DMDISTATE, 0x1c); | 615 | stv0900_write_reg(intp, DMDISTATE, 0x1c); |
611 | stv0900_write_reg(intp, CFRINIT1, 0); | 616 | stv0900_write_reg(intp, CFRINIT1, 0); |
612 | stv0900_write_reg(intp, CFRINIT0, 0); | 617 | stv0900_write_reg(intp, CFRINIT0, 0); |
@@ -790,7 +795,7 @@ static enum fe_stv0900_fec stv0900_get_vit_fec(struct stv0900_internal *intp, | |||
790 | return prate; | 795 | return prate; |
791 | } | 796 | } |
792 | 797 | ||
793 | void stv0900_set_dvbs1_track_car_loop(struct stv0900_internal *intp, | 798 | static void stv0900_set_dvbs1_track_car_loop(struct stv0900_internal *intp, |
794 | enum fe_stv0900_demod_num demod, | 799 | enum fe_stv0900_demod_num demod, |
795 | u32 srate) | 800 | u32 srate) |
796 | { | 801 | { |
@@ -976,8 +981,16 @@ static void stv0900_track_optimization(struct dvb_frontend *fe) | |||
976 | intp->rolloff) + 10000000; | 981 | intp->rolloff) + 10000000; |
977 | 982 | ||
978 | if ((intp->chip_id >= 0x20) || (blind_tun_sw == 1)) { | 983 | if ((intp->chip_id >= 0x20) || (blind_tun_sw == 1)) { |
979 | if (intp->srch_algo[demod] != STV0900_WARM_START) | 984 | if (intp->srch_algo[demod] != STV0900_WARM_START) { |
980 | stv0900_set_bandwidth(fe, intp->bw[demod]); | 985 | if (intp->tuner_type[demod] == 3) |
986 | stv0900_set_tuner_auto(intp, | ||
987 | intp->freq[demod], | ||
988 | intp->bw[demod], | ||
989 | demod); | ||
990 | else | ||
991 | stv0900_set_bandwidth(fe, | ||
992 | intp->bw[demod]); | ||
993 | } | ||
981 | } | 994 | } |
982 | 995 | ||
983 | if ((intp->srch_algo[demod] == STV0900_BLIND_SEARCH) || | 996 | if ((intp->srch_algo[demod] == STV0900_BLIND_SEARCH) || |
@@ -1202,7 +1215,11 @@ fe_stv0900_signal_type stv0900_get_signal_params(struct dvb_frontend *fe) | |||
1202 | } | 1215 | } |
1203 | 1216 | ||
1204 | result->standard = stv0900_get_standard(fe, d); | 1217 | result->standard = stv0900_get_standard(fe, d); |
1205 | result->frequency = stv0900_get_tuner_freq(fe); | 1218 | if (intp->tuner_type[demod] == 3) |
1219 | result->frequency = stv0900_get_freq_auto(intp, d); | ||
1220 | else | ||
1221 | result->frequency = stv0900_get_tuner_freq(fe); | ||
1222 | |||
1206 | offsetFreq = stv0900_get_carr_freq(intp, intp->mclk, d) / 1000; | 1223 | offsetFreq = stv0900_get_carr_freq(intp, intp->mclk, d) / 1000; |
1207 | result->frequency += offsetFreq; | 1224 | result->frequency += offsetFreq; |
1208 | result->symbol_rate = stv0900_get_symbol_rate(intp, intp->mclk, d); | 1225 | result->symbol_rate = stv0900_get_symbol_rate(intp, intp->mclk, d); |
@@ -1213,6 +1230,9 @@ fe_stv0900_signal_type stv0900_get_signal_params(struct dvb_frontend *fe) | |||
1213 | result->pilot = stv0900_get_bits(intp, DEMOD_TYPE) & 0x01; | 1230 | result->pilot = stv0900_get_bits(intp, DEMOD_TYPE) & 0x01; |
1214 | result->frame_len = ((u32)stv0900_get_bits(intp, DEMOD_TYPE)) >> 1; | 1231 | result->frame_len = ((u32)stv0900_get_bits(intp, DEMOD_TYPE)) >> 1; |
1215 | result->rolloff = stv0900_get_bits(intp, ROLLOFF_STATUS); | 1232 | result->rolloff = stv0900_get_bits(intp, ROLLOFF_STATUS); |
1233 | |||
1234 | dprintk("%s: modcode=0x%x \n", __func__, result->modcode); | ||
1235 | |||
1216 | switch (result->standard) { | 1236 | switch (result->standard) { |
1217 | case STV0900_DVBS2_STANDARD: | 1237 | case STV0900_DVBS2_STANDARD: |
1218 | result->spectrum = stv0900_get_bits(intp, SPECINV_DEMOD); | 1238 | result->spectrum = stv0900_get_bits(intp, SPECINV_DEMOD); |
@@ -1239,7 +1259,11 @@ fe_stv0900_signal_type stv0900_get_signal_params(struct dvb_frontend *fe) | |||
1239 | if ((intp->srch_algo[d] == STV0900_BLIND_SEARCH) || | 1259 | if ((intp->srch_algo[d] == STV0900_BLIND_SEARCH) || |
1240 | (intp->symbol_rate[d] < 10000000)) { | 1260 | (intp->symbol_rate[d] < 10000000)) { |
1241 | offsetFreq = result->frequency - intp->freq[d]; | 1261 | offsetFreq = result->frequency - intp->freq[d]; |
1242 | intp->freq[d] = stv0900_get_tuner_freq(fe); | 1262 | if (intp->tuner_type[demod] == 3) |
1263 | intp->freq[d] = stv0900_get_freq_auto(intp, d); | ||
1264 | else | ||
1265 | intp->freq[d] = stv0900_get_tuner_freq(fe); | ||
1266 | |||
1243 | if (ABS(offsetFreq) <= ((intp->srch_range[d] / 2000) + 500)) | 1267 | if (ABS(offsetFreq) <= ((intp->srch_range[d] / 2000) + 500)) |
1244 | range = STV0900_RANGEOK; | 1268 | range = STV0900_RANGEOK; |
1245 | else if (ABS(offsetFreq) <= | 1269 | else if (ABS(offsetFreq) <= |
@@ -1481,7 +1505,12 @@ static u32 stv0900_search_srate_coarse(struct dvb_frontend *fe) | |||
1481 | else | 1505 | else |
1482 | tuner_freq -= (current_step * currier_step); | 1506 | tuner_freq -= (current_step * currier_step); |
1483 | 1507 | ||
1484 | stv0900_set_tuner(fe, tuner_freq, intp->bw[demod]); | 1508 | if (intp->tuner_type[demod] == 3) |
1509 | stv0900_set_tuner_auto(intp, tuner_freq, | ||
1510 | intp->bw[demod], demod); | ||
1511 | else | ||
1512 | stv0900_set_tuner(fe, tuner_freq, | ||
1513 | intp->bw[demod]); | ||
1485 | } | 1514 | } |
1486 | } | 1515 | } |
1487 | 1516 | ||
@@ -1608,7 +1637,8 @@ static int stv0900_blind_search_algo(struct dvb_frontend *fe) | |||
1608 | 1637 | ||
1609 | agc2_int = stv0900_blind_check_agc2_min_level(intp, demod); | 1638 | agc2_int = stv0900_blind_check_agc2_min_level(intp, demod); |
1610 | 1639 | ||
1611 | if (agc2_int > STV0900_BLIND_SEARCH_AGC2_TH) | 1640 | dprintk("%s agc2_int=%d agc2_th=%d \n", __func__, agc2_int, agc2_th); |
1641 | if (agc2_int > agc2_th) | ||
1612 | return FALSE; | 1642 | return FALSE; |
1613 | 1643 | ||
1614 | if (intp->chip_id == 0x10) | 1644 | if (intp->chip_id == 0x10) |
@@ -1875,7 +1905,11 @@ enum fe_stv0900_signal_type stv0900_algo(struct dvb_frontend *fe) | |||
1875 | 1905 | ||
1876 | } | 1906 | } |
1877 | 1907 | ||
1878 | stv0900_set_tuner(fe, intp->freq[demod], intp->bw[demod]); | 1908 | if (intp->tuner_type[demod] == 3) |
1909 | stv0900_set_tuner_auto(intp, intp->freq[demod], | ||
1910 | intp->bw[demod], demod); | ||
1911 | else | ||
1912 | stv0900_set_tuner(fe, intp->freq[demod], intp->bw[demod]); | ||
1879 | 1913 | ||
1880 | agc1_power = MAKEWORD(stv0900_get_bits(intp, AGCIQ_VALUE1), | 1914 | agc1_power = MAKEWORD(stv0900_get_bits(intp, AGCIQ_VALUE1), |
1881 | stv0900_get_bits(intp, AGCIQ_VALUE0)); | 1915 | stv0900_get_bits(intp, AGCIQ_VALUE0)); |
diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c index 1573466a5c74..c52c3357dc54 100644 --- a/drivers/media/dvb/frontends/stv090x.c +++ b/drivers/media/dvb/frontends/stv090x.c | |||
@@ -37,7 +37,82 @@ | |||
37 | static unsigned int verbose; | 37 | static unsigned int verbose; |
38 | module_param(verbose, int, 0644); | 38 | module_param(verbose, int, 0644); |
39 | 39 | ||
40 | struct mutex demod_lock; | 40 | /* internal params node */ |
41 | struct stv090x_dev { | ||
42 | /* pointer for internal params, one for each pair of demods */ | ||
43 | struct stv090x_internal *internal; | ||
44 | struct stv090x_dev *next_dev; | ||
45 | }; | ||
46 | |||
47 | /* first internal params */ | ||
48 | static struct stv090x_dev *stv090x_first_dev; | ||
49 | |||
50 | /* find chip by i2c adapter and i2c address */ | ||
51 | static struct stv090x_dev *find_dev(struct i2c_adapter *i2c_adap, | ||
52 | u8 i2c_addr) | ||
53 | { | ||
54 | struct stv090x_dev *temp_dev = stv090x_first_dev; | ||
55 | |||
56 | /* | ||
57 | Search of the last stv0900 chip or | ||
58 | find it by i2c adapter and i2c address */ | ||
59 | while ((temp_dev != NULL) && | ||
60 | ((temp_dev->internal->i2c_adap != i2c_adap) || | ||
61 | (temp_dev->internal->i2c_addr != i2c_addr))) { | ||
62 | |||
63 | temp_dev = temp_dev->next_dev; | ||
64 | } | ||
65 | |||
66 | return temp_dev; | ||
67 | } | ||
68 | |||
69 | /* deallocating chip */ | ||
70 | static void remove_dev(struct stv090x_internal *internal) | ||
71 | { | ||
72 | struct stv090x_dev *prev_dev = stv090x_first_dev; | ||
73 | struct stv090x_dev *del_dev = find_dev(internal->i2c_adap, | ||
74 | internal->i2c_addr); | ||
75 | |||
76 | if (del_dev != NULL) { | ||
77 | if (del_dev == stv090x_first_dev) { | ||
78 | stv090x_first_dev = del_dev->next_dev; | ||
79 | } else { | ||
80 | while (prev_dev->next_dev != del_dev) | ||
81 | prev_dev = prev_dev->next_dev; | ||
82 | |||
83 | prev_dev->next_dev = del_dev->next_dev; | ||
84 | } | ||
85 | |||
86 | kfree(del_dev); | ||
87 | } | ||
88 | } | ||
89 | |||
90 | /* allocating new chip */ | ||
91 | static struct stv090x_dev *append_internal(struct stv090x_internal *internal) | ||
92 | { | ||
93 | struct stv090x_dev *new_dev; | ||
94 | struct stv090x_dev *temp_dev; | ||
95 | |||
96 | new_dev = kmalloc(sizeof(struct stv090x_dev), GFP_KERNEL); | ||
97 | if (new_dev != NULL) { | ||
98 | new_dev->internal = internal; | ||
99 | new_dev->next_dev = NULL; | ||
100 | |||
101 | /* append to list */ | ||
102 | if (stv090x_first_dev == NULL) { | ||
103 | stv090x_first_dev = new_dev; | ||
104 | } else { | ||
105 | temp_dev = stv090x_first_dev; | ||
106 | while (temp_dev->next_dev != NULL) | ||
107 | temp_dev = temp_dev->next_dev; | ||
108 | |||
109 | temp_dev->next_dev = new_dev; | ||
110 | } | ||
111 | } | ||
112 | |||
113 | return new_dev; | ||
114 | } | ||
115 | |||
41 | 116 | ||
42 | /* DVBS1 and DSS C/N Lookup table */ | 117 | /* DVBS1 and DSS C/N Lookup table */ |
43 | static const struct stv090x_tab stv090x_s1cn_tab[] = { | 118 | static const struct stv090x_tab stv090x_s1cn_tab[] = { |
@@ -683,6 +758,9 @@ static int stv090x_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) | |||
683 | struct stv090x_state *state = fe->demodulator_priv; | 758 | struct stv090x_state *state = fe->demodulator_priv; |
684 | u32 reg; | 759 | u32 reg; |
685 | 760 | ||
761 | if (enable) | ||
762 | mutex_lock(&state->internal->tuner_lock); | ||
763 | |||
686 | reg = STV090x_READ_DEMOD(state, I2CRPT); | 764 | reg = STV090x_READ_DEMOD(state, I2CRPT); |
687 | if (enable) { | 765 | if (enable) { |
688 | dprintk(FE_DEBUG, 1, "Enable Gate"); | 766 | dprintk(FE_DEBUG, 1, "Enable Gate"); |
@@ -696,9 +774,14 @@ static int stv090x_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) | |||
696 | if ((STV090x_WRITE_DEMOD(state, I2CRPT, reg)) < 0) | 774 | if ((STV090x_WRITE_DEMOD(state, I2CRPT, reg)) < 0) |
697 | goto err; | 775 | goto err; |
698 | } | 776 | } |
777 | |||
778 | if (!enable) | ||
779 | mutex_unlock(&state->internal->tuner_lock); | ||
780 | |||
699 | return 0; | 781 | return 0; |
700 | err: | 782 | err: |
701 | dprintk(FE_ERROR, 1, "I/O error"); | 783 | dprintk(FE_ERROR, 1, "I/O error"); |
784 | mutex_unlock(&state->internal->tuner_lock); | ||
702 | return -1; | 785 | return -1; |
703 | } | 786 | } |
704 | 787 | ||
@@ -755,13 +838,13 @@ static int stv090x_set_srate(struct stv090x_state *state, u32 srate) | |||
755 | 838 | ||
756 | if (srate > 60000000) { | 839 | if (srate > 60000000) { |
757 | sym = (srate << 4); /* SR * 2^16 / master_clk */ | 840 | sym = (srate << 4); /* SR * 2^16 / master_clk */ |
758 | sym /= (state->mclk >> 12); | 841 | sym /= (state->internal->mclk >> 12); |
759 | } else if (srate > 6000000) { | 842 | } else if (srate > 6000000) { |
760 | sym = (srate << 6); | 843 | sym = (srate << 6); |
761 | sym /= (state->mclk >> 10); | 844 | sym /= (state->internal->mclk >> 10); |
762 | } else { | 845 | } else { |
763 | sym = (srate << 9); | 846 | sym = (srate << 9); |
764 | sym /= (state->mclk >> 7); | 847 | sym /= (state->internal->mclk >> 7); |
765 | } | 848 | } |
766 | 849 | ||
767 | if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0x7f) < 0) /* MSB */ | 850 | if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0x7f) < 0) /* MSB */ |
@@ -782,13 +865,13 @@ static int stv090x_set_max_srate(struct stv090x_state *state, u32 clk, u32 srate | |||
782 | srate = 105 * (srate / 100); | 865 | srate = 105 * (srate / 100); |
783 | if (srate > 60000000) { | 866 | if (srate > 60000000) { |
784 | sym = (srate << 4); /* SR * 2^16 / master_clk */ | 867 | sym = (srate << 4); /* SR * 2^16 / master_clk */ |
785 | sym /= (state->mclk >> 12); | 868 | sym /= (state->internal->mclk >> 12); |
786 | } else if (srate > 6000000) { | 869 | } else if (srate > 6000000) { |
787 | sym = (srate << 6); | 870 | sym = (srate << 6); |
788 | sym /= (state->mclk >> 10); | 871 | sym /= (state->internal->mclk >> 10); |
789 | } else { | 872 | } else { |
790 | sym = (srate << 9); | 873 | sym = (srate << 9); |
791 | sym /= (state->mclk >> 7); | 874 | sym /= (state->internal->mclk >> 7); |
792 | } | 875 | } |
793 | 876 | ||
794 | if (sym < 0x7fff) { | 877 | if (sym < 0x7fff) { |
@@ -816,13 +899,13 @@ static int stv090x_set_min_srate(struct stv090x_state *state, u32 clk, u32 srate | |||
816 | srate = 95 * (srate / 100); | 899 | srate = 95 * (srate / 100); |
817 | if (srate > 60000000) { | 900 | if (srate > 60000000) { |
818 | sym = (srate << 4); /* SR * 2^16 / master_clk */ | 901 | sym = (srate << 4); /* SR * 2^16 / master_clk */ |
819 | sym /= (state->mclk >> 12); | 902 | sym /= (state->internal->mclk >> 12); |
820 | } else if (srate > 6000000) { | 903 | } else if (srate > 6000000) { |
821 | sym = (srate << 6); | 904 | sym = (srate << 6); |
822 | sym /= (state->mclk >> 10); | 905 | sym /= (state->internal->mclk >> 10); |
823 | } else { | 906 | } else { |
824 | sym = (srate << 9); | 907 | sym = (srate << 9); |
825 | sym /= (state->mclk >> 7); | 908 | sym /= (state->internal->mclk >> 7); |
826 | } | 909 | } |
827 | 910 | ||
828 | if (STV090x_WRITE_DEMOD(state, SFRLOW1, ((sym >> 8) & 0x7f)) < 0) /* MSB */ | 911 | if (STV090x_WRITE_DEMOD(state, SFRLOW1, ((sym >> 8) & 0x7f)) < 0) /* MSB */ |
@@ -1103,21 +1186,21 @@ static int stv090x_vitclk_ctl(struct stv090x_state *state, int enable) | |||
1103 | 1186 | ||
1104 | switch (state->demod) { | 1187 | switch (state->demod) { |
1105 | case STV090x_DEMODULATOR_0: | 1188 | case STV090x_DEMODULATOR_0: |
1106 | mutex_lock(&demod_lock); | 1189 | mutex_lock(&state->internal->demod_lock); |
1107 | reg = stv090x_read_reg(state, STV090x_STOPCLK2); | 1190 | reg = stv090x_read_reg(state, STV090x_STOPCLK2); |
1108 | STV090x_SETFIELD(reg, STOP_CLKVIT1_FIELD, enable); | 1191 | STV090x_SETFIELD(reg, STOP_CLKVIT1_FIELD, enable); |
1109 | if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0) | 1192 | if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0) |
1110 | goto err; | 1193 | goto err; |
1111 | mutex_unlock(&demod_lock); | 1194 | mutex_unlock(&state->internal->demod_lock); |
1112 | break; | 1195 | break; |
1113 | 1196 | ||
1114 | case STV090x_DEMODULATOR_1: | 1197 | case STV090x_DEMODULATOR_1: |
1115 | mutex_lock(&demod_lock); | 1198 | mutex_lock(&state->internal->demod_lock); |
1116 | reg = stv090x_read_reg(state, STV090x_STOPCLK2); | 1199 | reg = stv090x_read_reg(state, STV090x_STOPCLK2); |
1117 | STV090x_SETFIELD(reg, STOP_CLKVIT2_FIELD, enable); | 1200 | STV090x_SETFIELD(reg, STOP_CLKVIT2_FIELD, enable); |
1118 | if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0) | 1201 | if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0) |
1119 | goto err; | 1202 | goto err; |
1120 | mutex_unlock(&demod_lock); | 1203 | mutex_unlock(&state->internal->demod_lock); |
1121 | break; | 1204 | break; |
1122 | 1205 | ||
1123 | default: | 1206 | default: |
@@ -1126,14 +1209,14 @@ static int stv090x_vitclk_ctl(struct stv090x_state *state, int enable) | |||
1126 | } | 1209 | } |
1127 | return 0; | 1210 | return 0; |
1128 | err: | 1211 | err: |
1129 | mutex_unlock(&demod_lock); | 1212 | mutex_unlock(&state->internal->demod_lock); |
1130 | dprintk(FE_ERROR, 1, "I/O error"); | 1213 | dprintk(FE_ERROR, 1, "I/O error"); |
1131 | return -1; | 1214 | return -1; |
1132 | } | 1215 | } |
1133 | 1216 | ||
1134 | static int stv090x_dvbs_track_crl(struct stv090x_state *state) | 1217 | static int stv090x_dvbs_track_crl(struct stv090x_state *state) |
1135 | { | 1218 | { |
1136 | if (state->dev_ver >= 0x30) { | 1219 | if (state->internal->dev_ver >= 0x30) { |
1137 | /* Set ACLC BCLC optimised value vs SR */ | 1220 | /* Set ACLC BCLC optimised value vs SR */ |
1138 | if (state->srate >= 15000000) { | 1221 | if (state->srate >= 15000000) { |
1139 | if (STV090x_WRITE_DEMOD(state, ACLC, 0x2b) < 0) | 1222 | if (STV090x_WRITE_DEMOD(state, ACLC, 0x2b) < 0) |
@@ -1215,7 +1298,7 @@ static int stv090x_delivery_search(struct stv090x_state *state) | |||
1215 | if (STV090x_WRITE_DEMOD(state, BCLC, 0x09) < 0) | 1298 | if (STV090x_WRITE_DEMOD(state, BCLC, 0x09) < 0) |
1216 | goto err; | 1299 | goto err; |
1217 | 1300 | ||
1218 | if (state->dev_ver <= 0x20) { | 1301 | if (state->internal->dev_ver <= 0x20) { |
1219 | /* enable S2 carrier loop */ | 1302 | /* enable S2 carrier loop */ |
1220 | if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0) | 1303 | if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0) |
1221 | goto err; | 1304 | goto err; |
@@ -1246,6 +1329,10 @@ static int stv090x_delivery_search(struct stv090x_state *state) | |||
1246 | default: | 1329 | default: |
1247 | /* enable DVB-S2 and DVB-S2 in Auto MODE */ | 1330 | /* enable DVB-S2 and DVB-S2 in Auto MODE */ |
1248 | reg = STV090x_READ_DEMOD(state, DMDCFGMD); | 1331 | reg = STV090x_READ_DEMOD(state, DMDCFGMD); |
1332 | STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0); | ||
1333 | STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0); | ||
1334 | if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) | ||
1335 | goto err; | ||
1249 | STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1); | 1336 | STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1); |
1250 | STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1); | 1337 | STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1); |
1251 | if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) | 1338 | if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) |
@@ -1257,7 +1344,7 @@ static int stv090x_delivery_search(struct stv090x_state *state) | |||
1257 | if (stv090x_dvbs_track_crl(state) < 0) | 1344 | if (stv090x_dvbs_track_crl(state) < 0) |
1258 | goto err; | 1345 | goto err; |
1259 | 1346 | ||
1260 | if (state->dev_ver <= 0x20) { | 1347 | if (state->internal->dev_ver <= 0x20) { |
1261 | /* enable S2 carrier loop */ | 1348 | /* enable S2 carrier loop */ |
1262 | if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0) | 1349 | if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0) |
1263 | goto err; | 1350 | goto err; |
@@ -1304,7 +1391,7 @@ static int stv090x_start_search(struct stv090x_state *state) | |||
1304 | if (STV090x_WRITE_DEMOD(state, DMDISTATE, reg) < 0) | 1391 | if (STV090x_WRITE_DEMOD(state, DMDISTATE, reg) < 0) |
1305 | goto err; | 1392 | goto err; |
1306 | 1393 | ||
1307 | if (state->dev_ver <= 0x20) { | 1394 | if (state->internal->dev_ver <= 0x20) { |
1308 | if (state->srate <= 5000000) { | 1395 | if (state->srate <= 5000000) { |
1309 | if (STV090x_WRITE_DEMOD(state, CARCFG, 0x44) < 0) | 1396 | if (STV090x_WRITE_DEMOD(state, CARCFG, 0x44) < 0) |
1310 | goto err; | 1397 | goto err; |
@@ -1348,7 +1435,7 @@ static int stv090x_start_search(struct stv090x_state *state) | |||
1348 | * CFR max = +1MHz | 1435 | * CFR max = +1MHz |
1349 | */ | 1436 | */ |
1350 | freq_abs = 1000 << 16; | 1437 | freq_abs = 1000 << 16; |
1351 | freq_abs /= (state->mclk / 1000); | 1438 | freq_abs /= (state->internal->mclk / 1000); |
1352 | freq = (s16) freq_abs; | 1439 | freq = (s16) freq_abs; |
1353 | } else { | 1440 | } else { |
1354 | /* COLD Start | 1441 | /* COLD Start |
@@ -1358,7 +1445,7 @@ static int stv090x_start_search(struct stv090x_state *state) | |||
1358 | */ | 1445 | */ |
1359 | freq_abs = (state->search_range / 2000) + 600; | 1446 | freq_abs = (state->search_range / 2000) + 600; |
1360 | freq_abs = freq_abs << 16; | 1447 | freq_abs = freq_abs << 16; |
1361 | freq_abs /= (state->mclk / 1000); | 1448 | freq_abs /= (state->internal->mclk / 1000); |
1362 | freq = (s16) freq_abs; | 1449 | freq = (s16) freq_abs; |
1363 | } | 1450 | } |
1364 | 1451 | ||
@@ -1381,7 +1468,7 @@ static int stv090x_start_search(struct stv090x_state *state) | |||
1381 | if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0) < 0) | 1468 | if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0) < 0) |
1382 | goto err; | 1469 | goto err; |
1383 | 1470 | ||
1384 | if (state->dev_ver >= 0x20) { | 1471 | if (state->internal->dev_ver >= 0x20) { |
1385 | if (STV090x_WRITE_DEMOD(state, EQUALCFG, 0x41) < 0) | 1472 | if (STV090x_WRITE_DEMOD(state, EQUALCFG, 0x41) < 0) |
1386 | goto err; | 1473 | goto err; |
1387 | if (STV090x_WRITE_DEMOD(state, FFECFG, 0x41) < 0) | 1474 | if (STV090x_WRITE_DEMOD(state, FFECFG, 0x41) < 0) |
@@ -1418,10 +1505,10 @@ static int stv090x_start_search(struct stv090x_state *state) | |||
1418 | if (STV090x_WRITE_DEMOD(state, RTC, 0x88) < 0) | 1505 | if (STV090x_WRITE_DEMOD(state, RTC, 0x88) < 0) |
1419 | goto err; | 1506 | goto err; |
1420 | 1507 | ||
1421 | if (state->dev_ver >= 0x20) { | 1508 | if (state->internal->dev_ver >= 0x20) { |
1422 | /*Frequency offset detector setting*/ | 1509 | /*Frequency offset detector setting*/ |
1423 | if (state->srate < 2000000) { | 1510 | if (state->srate < 2000000) { |
1424 | if (state->dev_ver <= 0x20) { | 1511 | if (state->internal->dev_ver <= 0x20) { |
1425 | /* Cut 2 */ | 1512 | /* Cut 2 */ |
1426 | if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x39) < 0) | 1513 | if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x39) < 0) |
1427 | goto err; | 1514 | goto err; |
@@ -1512,7 +1599,7 @@ static int stv090x_get_agc2_min_level(struct stv090x_state *state) | |||
1512 | steps = 1; | 1599 | steps = 1; |
1513 | 1600 | ||
1514 | dir = 1; | 1601 | dir = 1; |
1515 | freq_step = (1000000 * 256) / (state->mclk / 256); | 1602 | freq_step = (1000000 * 256) / (state->internal->mclk / 256); |
1516 | freq_init = 0; | 1603 | freq_init = 0; |
1517 | 1604 | ||
1518 | for (i = 0; i < steps; i++) { | 1605 | for (i = 0; i < steps; i++) { |
@@ -1583,7 +1670,7 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state) | |||
1583 | u32 srate_coarse = 0, agc2 = 0, car_step = 1200, reg; | 1670 | u32 srate_coarse = 0, agc2 = 0, car_step = 1200, reg; |
1584 | u32 agc2th; | 1671 | u32 agc2th; |
1585 | 1672 | ||
1586 | if (state->dev_ver >= 0x30) | 1673 | if (state->internal->dev_ver >= 0x30) |
1587 | agc2th = 0x2e00; | 1674 | agc2th = 0x2e00; |
1588 | else | 1675 | else |
1589 | agc2th = 0x1f00; | 1676 | agc2th = 0x1f00; |
@@ -1619,13 +1706,13 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state) | |||
1619 | if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x50) < 0) | 1706 | if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x50) < 0) |
1620 | goto err; | 1707 | goto err; |
1621 | 1708 | ||
1622 | if (state->dev_ver >= 0x30) { | 1709 | if (state->internal->dev_ver >= 0x30) { |
1623 | if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x99) < 0) | 1710 | if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x99) < 0) |
1624 | goto err; | 1711 | goto err; |
1625 | if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x98) < 0) | 1712 | if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x98) < 0) |
1626 | goto err; | 1713 | goto err; |
1627 | 1714 | ||
1628 | } else if (state->dev_ver >= 0x20) { | 1715 | } else if (state->internal->dev_ver >= 0x20) { |
1629 | if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x6a) < 0) | 1716 | if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x6a) < 0) |
1630 | goto err; | 1717 | goto err; |
1631 | if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x95) < 0) | 1718 | if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x95) < 0) |
@@ -1677,7 +1764,7 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state) | |||
1677 | STV090x_READ_DEMOD(state, AGC2I0); | 1764 | STV090x_READ_DEMOD(state, AGC2I0); |
1678 | } | 1765 | } |
1679 | agc2 /= 10; | 1766 | agc2 /= 10; |
1680 | srate_coarse = stv090x_get_srate(state, state->mclk); | 1767 | srate_coarse = stv090x_get_srate(state, state->internal->mclk); |
1681 | cur_step++; | 1768 | cur_step++; |
1682 | dir *= -1; | 1769 | dir *= -1; |
1683 | if ((tmg_cpt >= 5) && (agc2 < agc2th) && | 1770 | if ((tmg_cpt >= 5) && (agc2 < agc2th) && |
@@ -1695,12 +1782,12 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state) | |||
1695 | 1782 | ||
1696 | if (state->config->tuner_set_frequency) { | 1783 | if (state->config->tuner_set_frequency) { |
1697 | if (state->config->tuner_set_frequency(fe, freq) < 0) | 1784 | if (state->config->tuner_set_frequency(fe, freq) < 0) |
1698 | goto err; | 1785 | goto err_gateoff; |
1699 | } | 1786 | } |
1700 | 1787 | ||
1701 | if (state->config->tuner_set_bandwidth) { | 1788 | if (state->config->tuner_set_bandwidth) { |
1702 | if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0) | 1789 | if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0) |
1703 | goto err; | 1790 | goto err_gateoff; |
1704 | } | 1791 | } |
1705 | 1792 | ||
1706 | if (stv090x_i2c_gate_ctrl(fe, 0) < 0) | 1793 | if (stv090x_i2c_gate_ctrl(fe, 0) < 0) |
@@ -1713,7 +1800,7 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state) | |||
1713 | 1800 | ||
1714 | if (state->config->tuner_get_status) { | 1801 | if (state->config->tuner_get_status) { |
1715 | if (state->config->tuner_get_status(fe, ®) < 0) | 1802 | if (state->config->tuner_get_status(fe, ®) < 0) |
1716 | goto err; | 1803 | goto err_gateoff; |
1717 | } | 1804 | } |
1718 | 1805 | ||
1719 | if (reg) | 1806 | if (reg) |
@@ -1729,9 +1816,12 @@ static u32 stv090x_srate_srch_coarse(struct stv090x_state *state) | |||
1729 | if (!tmg_lock) | 1816 | if (!tmg_lock) |
1730 | srate_coarse = 0; | 1817 | srate_coarse = 0; |
1731 | else | 1818 | else |
1732 | srate_coarse = stv090x_get_srate(state, state->mclk); | 1819 | srate_coarse = stv090x_get_srate(state, state->internal->mclk); |
1733 | 1820 | ||
1734 | return srate_coarse; | 1821 | return srate_coarse; |
1822 | |||
1823 | err_gateoff: | ||
1824 | stv090x_i2c_gate_ctrl(fe, 0); | ||
1735 | err: | 1825 | err: |
1736 | dprintk(FE_ERROR, 1, "I/O error"); | 1826 | dprintk(FE_ERROR, 1, "I/O error"); |
1737 | return -1; | 1827 | return -1; |
@@ -1741,7 +1831,7 @@ static u32 stv090x_srate_srch_fine(struct stv090x_state *state) | |||
1741 | { | 1831 | { |
1742 | u32 srate_coarse, freq_coarse, sym, reg; | 1832 | u32 srate_coarse, freq_coarse, sym, reg; |
1743 | 1833 | ||
1744 | srate_coarse = stv090x_get_srate(state, state->mclk); | 1834 | srate_coarse = stv090x_get_srate(state, state->internal->mclk); |
1745 | freq_coarse = STV090x_READ_DEMOD(state, CFR2) << 8; | 1835 | freq_coarse = STV090x_READ_DEMOD(state, CFR2) << 8; |
1746 | freq_coarse |= STV090x_READ_DEMOD(state, CFR1); | 1836 | freq_coarse |= STV090x_READ_DEMOD(state, CFR1); |
1747 | sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */ | 1837 | sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */ |
@@ -1767,10 +1857,10 @@ static u32 stv090x_srate_srch_fine(struct stv090x_state *state) | |||
1767 | if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0) | 1857 | if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0) |
1768 | goto err; | 1858 | goto err; |
1769 | 1859 | ||
1770 | if (state->dev_ver >= 0x30) { | 1860 | if (state->internal->dev_ver >= 0x30) { |
1771 | if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x79) < 0) | 1861 | if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x79) < 0) |
1772 | goto err; | 1862 | goto err; |
1773 | } else if (state->dev_ver >= 0x20) { | 1863 | } else if (state->internal->dev_ver >= 0x20) { |
1774 | if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0) | 1864 | if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0) |
1775 | goto err; | 1865 | goto err; |
1776 | } | 1866 | } |
@@ -1778,20 +1868,20 @@ static u32 stv090x_srate_srch_fine(struct stv090x_state *state) | |||
1778 | if (srate_coarse > 3000000) { | 1868 | if (srate_coarse > 3000000) { |
1779 | sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */ | 1869 | sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */ |
1780 | sym = (sym / 1000) * 65536; | 1870 | sym = (sym / 1000) * 65536; |
1781 | sym /= (state->mclk / 1000); | 1871 | sym /= (state->internal->mclk / 1000); |
1782 | if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0) | 1872 | if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0) |
1783 | goto err; | 1873 | goto err; |
1784 | if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0) | 1874 | if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0) |
1785 | goto err; | 1875 | goto err; |
1786 | sym = 10 * (srate_coarse / 13); /* SFRLOW = SFR - 30% */ | 1876 | sym = 10 * (srate_coarse / 13); /* SFRLOW = SFR - 30% */ |
1787 | sym = (sym / 1000) * 65536; | 1877 | sym = (sym / 1000) * 65536; |
1788 | sym /= (state->mclk / 1000); | 1878 | sym /= (state->internal->mclk / 1000); |
1789 | if (STV090x_WRITE_DEMOD(state, SFRLOW1, (sym >> 8) & 0x7f) < 0) | 1879 | if (STV090x_WRITE_DEMOD(state, SFRLOW1, (sym >> 8) & 0x7f) < 0) |
1790 | goto err; | 1880 | goto err; |
1791 | if (STV090x_WRITE_DEMOD(state, SFRLOW0, sym & 0xff) < 0) | 1881 | if (STV090x_WRITE_DEMOD(state, SFRLOW0, sym & 0xff) < 0) |
1792 | goto err; | 1882 | goto err; |
1793 | sym = (srate_coarse / 1000) * 65536; | 1883 | sym = (srate_coarse / 1000) * 65536; |
1794 | sym /= (state->mclk / 1000); | 1884 | sym /= (state->internal->mclk / 1000); |
1795 | if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0xff) < 0) | 1885 | if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0xff) < 0) |
1796 | goto err; | 1886 | goto err; |
1797 | if (STV090x_WRITE_DEMOD(state, SFRINIT0, sym & 0xff) < 0) | 1887 | if (STV090x_WRITE_DEMOD(state, SFRINIT0, sym & 0xff) < 0) |
@@ -1799,20 +1889,20 @@ static u32 stv090x_srate_srch_fine(struct stv090x_state *state) | |||
1799 | } else { | 1889 | } else { |
1800 | sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */ | 1890 | sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */ |
1801 | sym = (sym / 100) * 65536; | 1891 | sym = (sym / 100) * 65536; |
1802 | sym /= (state->mclk / 100); | 1892 | sym /= (state->internal->mclk / 100); |
1803 | if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0) | 1893 | if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0) |
1804 | goto err; | 1894 | goto err; |
1805 | if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0) | 1895 | if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0) |
1806 | goto err; | 1896 | goto err; |
1807 | sym = 10 * (srate_coarse / 14); /* SFRLOW = SFR - 30% */ | 1897 | sym = 10 * (srate_coarse / 14); /* SFRLOW = SFR - 30% */ |
1808 | sym = (sym / 100) * 65536; | 1898 | sym = (sym / 100) * 65536; |
1809 | sym /= (state->mclk / 100); | 1899 | sym /= (state->internal->mclk / 100); |
1810 | if (STV090x_WRITE_DEMOD(state, SFRLOW1, (sym >> 8) & 0x7f) < 0) | 1900 | if (STV090x_WRITE_DEMOD(state, SFRLOW1, (sym >> 8) & 0x7f) < 0) |
1811 | goto err; | 1901 | goto err; |
1812 | if (STV090x_WRITE_DEMOD(state, SFRLOW0, sym & 0xff) < 0) | 1902 | if (STV090x_WRITE_DEMOD(state, SFRLOW0, sym & 0xff) < 0) |
1813 | goto err; | 1903 | goto err; |
1814 | sym = (srate_coarse / 100) * 65536; | 1904 | sym = (srate_coarse / 100) * 65536; |
1815 | sym /= (state->mclk / 100); | 1905 | sym /= (state->internal->mclk / 100); |
1816 | if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0xff) < 0) | 1906 | if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0xff) < 0) |
1817 | goto err; | 1907 | goto err; |
1818 | if (STV090x_WRITE_DEMOD(state, SFRINIT0, sym & 0xff) < 0) | 1908 | if (STV090x_WRITE_DEMOD(state, SFRINIT0, sym & 0xff) < 0) |
@@ -1874,18 +1964,19 @@ static int stv090x_blind_search(struct stv090x_state *state) | |||
1874 | u32 agc2, reg, srate_coarse; | 1964 | u32 agc2, reg, srate_coarse; |
1875 | s32 cpt_fail, agc2_ovflw, i; | 1965 | s32 cpt_fail, agc2_ovflw, i; |
1876 | u8 k_ref, k_max, k_min; | 1966 | u8 k_ref, k_max, k_min; |
1877 | int coarse_fail, lock; | 1967 | int coarse_fail = 0; |
1968 | int lock; | ||
1878 | 1969 | ||
1879 | k_max = 110; | 1970 | k_max = 110; |
1880 | k_min = 10; | 1971 | k_min = 10; |
1881 | 1972 | ||
1882 | agc2 = stv090x_get_agc2_min_level(state); | 1973 | agc2 = stv090x_get_agc2_min_level(state); |
1883 | 1974 | ||
1884 | if (agc2 > STV090x_SEARCH_AGC2_TH(state->dev_ver)) { | 1975 | if (agc2 > STV090x_SEARCH_AGC2_TH(state->internal->dev_ver)) { |
1885 | lock = 0; | 1976 | lock = 0; |
1886 | } else { | 1977 | } else { |
1887 | 1978 | ||
1888 | if (state->dev_ver <= 0x20) { | 1979 | if (state->internal->dev_ver <= 0x20) { |
1889 | if (STV090x_WRITE_DEMOD(state, CARCFG, 0xc4) < 0) | 1980 | if (STV090x_WRITE_DEMOD(state, CARCFG, 0xc4) < 0) |
1890 | goto err; | 1981 | goto err; |
1891 | } else { | 1982 | } else { |
@@ -1897,7 +1988,7 @@ static int stv090x_blind_search(struct stv090x_state *state) | |||
1897 | if (STV090x_WRITE_DEMOD(state, RTCS2, 0x44) < 0) | 1988 | if (STV090x_WRITE_DEMOD(state, RTCS2, 0x44) < 0) |
1898 | goto err; | 1989 | goto err; |
1899 | 1990 | ||
1900 | if (state->dev_ver >= 0x20) { | 1991 | if (state->internal->dev_ver >= 0x20) { |
1901 | if (STV090x_WRITE_DEMOD(state, EQUALCFG, 0x41) < 0) | 1992 | if (STV090x_WRITE_DEMOD(state, EQUALCFG, 0x41) < 0) |
1902 | goto err; | 1993 | goto err; |
1903 | if (STV090x_WRITE_DEMOD(state, FFECFG, 0x41) < 0) | 1994 | if (STV090x_WRITE_DEMOD(state, FFECFG, 0x41) < 0) |
@@ -1956,7 +2047,7 @@ static int stv090x_chk_tmg(struct stv090x_state *state) | |||
1956 | u32 reg; | 2047 | u32 reg; |
1957 | s32 tmg_cpt = 0, i; | 2048 | s32 tmg_cpt = 0, i; |
1958 | u8 freq, tmg_thh, tmg_thl; | 2049 | u8 freq, tmg_thh, tmg_thl; |
1959 | int tmg_lock; | 2050 | int tmg_lock = 0; |
1960 | 2051 | ||
1961 | freq = STV090x_READ_DEMOD(state, CARFREQ); | 2052 | freq = STV090x_READ_DEMOD(state, CARFREQ); |
1962 | tmg_thh = STV090x_READ_DEMOD(state, TMGTHRISE); | 2053 | tmg_thh = STV090x_READ_DEMOD(state, TMGTHRISE); |
@@ -2080,12 +2171,12 @@ static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd) | |||
2080 | 2171 | ||
2081 | if (state->config->tuner_set_frequency) { | 2172 | if (state->config->tuner_set_frequency) { |
2082 | if (state->config->tuner_set_frequency(fe, freq) < 0) | 2173 | if (state->config->tuner_set_frequency(fe, freq) < 0) |
2083 | goto err; | 2174 | goto err_gateoff; |
2084 | } | 2175 | } |
2085 | 2176 | ||
2086 | if (state->config->tuner_set_bandwidth) { | 2177 | if (state->config->tuner_set_bandwidth) { |
2087 | if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0) | 2178 | if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0) |
2088 | goto err; | 2179 | goto err_gateoff; |
2089 | } | 2180 | } |
2090 | 2181 | ||
2091 | if (stv090x_i2c_gate_ctrl(fe, 0) < 0) | 2182 | if (stv090x_i2c_gate_ctrl(fe, 0) < 0) |
@@ -2098,7 +2189,7 @@ static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd) | |||
2098 | 2189 | ||
2099 | if (state->config->tuner_get_status) { | 2190 | if (state->config->tuner_get_status) { |
2100 | if (state->config->tuner_get_status(fe, ®) < 0) | 2191 | if (state->config->tuner_get_status(fe, ®) < 0) |
2101 | goto err; | 2192 | goto err_gateoff; |
2102 | } | 2193 | } |
2103 | 2194 | ||
2104 | if (reg) | 2195 | if (reg) |
@@ -2129,6 +2220,8 @@ static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd) | |||
2129 | 2220 | ||
2130 | return lock; | 2221 | return lock; |
2131 | 2222 | ||
2223 | err_gateoff: | ||
2224 | stv090x_i2c_gate_ctrl(fe, 0); | ||
2132 | err: | 2225 | err: |
2133 | dprintk(FE_ERROR, 1, "I/O error"); | 2226 | dprintk(FE_ERROR, 1, "I/O error"); |
2134 | return -1; | 2227 | return -1; |
@@ -2142,13 +2235,13 @@ static int stv090x_get_loop_params(struct stv090x_state *state, s32 *freq_inc, s | |||
2142 | car_max = state->search_range / 1000; | 2235 | car_max = state->search_range / 1000; |
2143 | car_max += car_max / 10; | 2236 | car_max += car_max / 10; |
2144 | car_max = 65536 * (car_max / 2); | 2237 | car_max = 65536 * (car_max / 2); |
2145 | car_max /= (state->mclk / 1000); | 2238 | car_max /= (state->internal->mclk / 1000); |
2146 | 2239 | ||
2147 | if (car_max > 0x4000) | 2240 | if (car_max > 0x4000) |
2148 | car_max = 0x4000 ; /* maxcarrier should be<= +-1/4 Mclk */ | 2241 | car_max = 0x4000 ; /* maxcarrier should be<= +-1/4 Mclk */ |
2149 | 2242 | ||
2150 | inc = srate; | 2243 | inc = srate; |
2151 | inc /= state->mclk / 1000; | 2244 | inc /= state->internal->mclk / 1000; |
2152 | inc *= 256; | 2245 | inc *= 256; |
2153 | inc *= 256; | 2246 | inc *= 256; |
2154 | inc /= 1000; | 2247 | inc /= 1000; |
@@ -2209,7 +2302,7 @@ static int stv090x_chk_signal(struct stv090x_state *state) | |||
2209 | 2302 | ||
2210 | car_max += (car_max / 10); /* 10% margin */ | 2303 | car_max += (car_max / 10); /* 10% margin */ |
2211 | car_max = (65536 * car_max / 2); | 2304 | car_max = (65536 * car_max / 2); |
2212 | car_max /= state->mclk / 1000; | 2305 | car_max /= state->internal->mclk / 1000; |
2213 | 2306 | ||
2214 | if (car_max > 0x4000) | 2307 | if (car_max > 0x4000) |
2215 | car_max = 0x4000; | 2308 | car_max = 0x4000; |
@@ -2234,7 +2327,7 @@ static int stv090x_search_car_loop(struct stv090x_state *state, s32 inc, s32 tim | |||
2234 | car_max = state->search_range / 1000; | 2327 | car_max = state->search_range / 1000; |
2235 | car_max += (car_max / 10); | 2328 | car_max += (car_max / 10); |
2236 | car_max = (65536 * car_max / 2); | 2329 | car_max = (65536 * car_max / 2); |
2237 | car_max /= (state->mclk / 1000); | 2330 | car_max /= (state->internal->mclk / 1000); |
2238 | if (car_max > 0x4000) | 2331 | if (car_max > 0x4000) |
2239 | car_max = 0x4000; | 2332 | car_max = 0x4000; |
2240 | 2333 | ||
@@ -2304,7 +2397,7 @@ static int stv090x_sw_algo(struct stv090x_state *state) | |||
2304 | case STV090x_SEARCH_DVBS1: | 2397 | case STV090x_SEARCH_DVBS1: |
2305 | case STV090x_SEARCH_DSS: | 2398 | case STV090x_SEARCH_DSS: |
2306 | /* accelerate the frequency detector */ | 2399 | /* accelerate the frequency detector */ |
2307 | if (state->dev_ver >= 0x20) { | 2400 | if (state->internal->dev_ver >= 0x20) { |
2308 | if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x3B) < 0) | 2401 | if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x3B) < 0) |
2309 | goto err; | 2402 | goto err; |
2310 | } | 2403 | } |
@@ -2315,7 +2408,7 @@ static int stv090x_sw_algo(struct stv090x_state *state) | |||
2315 | break; | 2408 | break; |
2316 | 2409 | ||
2317 | case STV090x_SEARCH_DVBS2: | 2410 | case STV090x_SEARCH_DVBS2: |
2318 | if (state->dev_ver >= 0x20) { | 2411 | if (state->internal->dev_ver >= 0x20) { |
2319 | if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0) | 2412 | if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0) |
2320 | goto err; | 2413 | goto err; |
2321 | } | 2414 | } |
@@ -2328,7 +2421,7 @@ static int stv090x_sw_algo(struct stv090x_state *state) | |||
2328 | case STV090x_SEARCH_AUTO: | 2421 | case STV090x_SEARCH_AUTO: |
2329 | default: | 2422 | default: |
2330 | /* accelerate the frequency detector */ | 2423 | /* accelerate the frequency detector */ |
2331 | if (state->dev_ver >= 0x20) { | 2424 | if (state->internal->dev_ver >= 0x20) { |
2332 | if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x3b) < 0) | 2425 | if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x3b) < 0) |
2333 | goto err; | 2426 | goto err; |
2334 | if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0) | 2427 | if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0) |
@@ -2350,7 +2443,7 @@ static int stv090x_sw_algo(struct stv090x_state *state) | |||
2350 | /*run the SW search 2 times maximum*/ | 2443 | /*run the SW search 2 times maximum*/ |
2351 | if (lock || no_signal || (trials == 2)) { | 2444 | if (lock || no_signal || (trials == 2)) { |
2352 | /*Check if the demod is not losing lock in DVBS2*/ | 2445 | /*Check if the demod is not losing lock in DVBS2*/ |
2353 | if (state->dev_ver >= 0x20) { | 2446 | if (state->internal->dev_ver >= 0x20) { |
2354 | if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0) | 2447 | if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0) |
2355 | goto err; | 2448 | goto err; |
2356 | if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0) | 2449 | if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0) |
@@ -2372,7 +2465,7 @@ static int stv090x_sw_algo(struct stv090x_state *state) | |||
2372 | /*FALSE lock, The demod is loosing lock */ | 2465 | /*FALSE lock, The demod is loosing lock */ |
2373 | lock = 0; | 2466 | lock = 0; |
2374 | if (trials < 2) { | 2467 | if (trials < 2) { |
2375 | if (state->dev_ver >= 0x20) { | 2468 | if (state->internal->dev_ver >= 0x20) { |
2376 | if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0) | 2469 | if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0) |
2377 | goto err; | 2470 | goto err; |
2378 | } | 2471 | } |
@@ -2422,11 +2515,11 @@ static s32 stv090x_get_car_freq(struct stv090x_state *state, u32 mclk) | |||
2422 | derot |= STV090x_READ_DEMOD(state, CFR0); | 2515 | derot |= STV090x_READ_DEMOD(state, CFR0); |
2423 | 2516 | ||
2424 | derot = comp2(derot, 24); | 2517 | derot = comp2(derot, 24); |
2425 | int_1 = state->mclk >> 12; | 2518 | int_1 = mclk >> 12; |
2426 | int_2 = derot >> 12; | 2519 | int_2 = derot >> 12; |
2427 | 2520 | ||
2428 | /* carrier_frequency = MasterClock * Reg / 2^24 */ | 2521 | /* carrier_frequency = MasterClock * Reg / 2^24 */ |
2429 | tmp_1 = state->mclk % 0x1000; | 2522 | tmp_1 = mclk % 0x1000; |
2430 | tmp_2 = derot % 0x1000; | 2523 | tmp_2 = derot % 0x1000; |
2431 | 2524 | ||
2432 | derot = (int_1 * int_2) + | 2525 | derot = (int_1 * int_2) + |
@@ -2502,13 +2595,13 @@ static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *st | |||
2502 | 2595 | ||
2503 | if (state->config->tuner_get_frequency) { | 2596 | if (state->config->tuner_get_frequency) { |
2504 | if (state->config->tuner_get_frequency(fe, &state->frequency) < 0) | 2597 | if (state->config->tuner_get_frequency(fe, &state->frequency) < 0) |
2505 | goto err; | 2598 | goto err_gateoff; |
2506 | } | 2599 | } |
2507 | 2600 | ||
2508 | if (stv090x_i2c_gate_ctrl(fe, 0) < 0) | 2601 | if (stv090x_i2c_gate_ctrl(fe, 0) < 0) |
2509 | goto err; | 2602 | goto err; |
2510 | 2603 | ||
2511 | offst_freq = stv090x_get_car_freq(state, state->mclk) / 1000; | 2604 | offst_freq = stv090x_get_car_freq(state, state->internal->mclk) / 1000; |
2512 | state->frequency += offst_freq; | 2605 | state->frequency += offst_freq; |
2513 | 2606 | ||
2514 | if (stv090x_get_viterbi(state) < 0) | 2607 | if (stv090x_get_viterbi(state) < 0) |
@@ -2530,7 +2623,7 @@ static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *st | |||
2530 | 2623 | ||
2531 | if (state->config->tuner_get_frequency) { | 2624 | if (state->config->tuner_get_frequency) { |
2532 | if (state->config->tuner_get_frequency(fe, &state->frequency) < 0) | 2625 | if (state->config->tuner_get_frequency(fe, &state->frequency) < 0) |
2533 | goto err; | 2626 | goto err_gateoff; |
2534 | } | 2627 | } |
2535 | 2628 | ||
2536 | if (stv090x_i2c_gate_ctrl(fe, 0) < 0) | 2629 | if (stv090x_i2c_gate_ctrl(fe, 0) < 0) |
@@ -2550,6 +2643,9 @@ static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *st | |||
2550 | } | 2643 | } |
2551 | 2644 | ||
2552 | return STV090x_OUTOFRANGE; | 2645 | return STV090x_OUTOFRANGE; |
2646 | |||
2647 | err_gateoff: | ||
2648 | stv090x_i2c_gate_ctrl(fe, 0); | ||
2553 | err: | 2649 | err: |
2554 | dprintk(FE_ERROR, 1, "I/O error"); | 2650 | dprintk(FE_ERROR, 1, "I/O error"); |
2555 | return -1; | 2651 | return -1; |
@@ -2579,7 +2675,7 @@ static u8 stv090x_optimize_carloop(struct stv090x_state *state, enum stv090x_mod | |||
2579 | s32 i; | 2675 | s32 i; |
2580 | struct stv090x_long_frame_crloop *car_loop, *car_loop_qpsk_low, *car_loop_apsk_low; | 2676 | struct stv090x_long_frame_crloop *car_loop, *car_loop_qpsk_low, *car_loop_apsk_low; |
2581 | 2677 | ||
2582 | if (state->dev_ver == 0x20) { | 2678 | if (state->internal->dev_ver == 0x20) { |
2583 | car_loop = stv090x_s2_crl_cut20; | 2679 | car_loop = stv090x_s2_crl_cut20; |
2584 | car_loop_qpsk_low = stv090x_s2_lowqpsk_crl_cut20; | 2680 | car_loop_qpsk_low = stv090x_s2_lowqpsk_crl_cut20; |
2585 | car_loop_apsk_low = stv090x_s2_apsk_crl_cut20; | 2681 | car_loop_apsk_low = stv090x_s2_apsk_crl_cut20; |
@@ -2700,7 +2796,7 @@ static u8 stv090x_optimize_carloop_short(struct stv090x_state *state) | |||
2700 | break; | 2796 | break; |
2701 | } | 2797 | } |
2702 | 2798 | ||
2703 | if (state->dev_ver >= 0x30) { | 2799 | if (state->internal->dev_ver >= 0x30) { |
2704 | /* Cut 3.0 and up */ | 2800 | /* Cut 3.0 and up */ |
2705 | short_crl = stv090x_s2_short_crl_cut30; | 2801 | short_crl = stv090x_s2_short_crl_cut30; |
2706 | } else { | 2802 | } else { |
@@ -2732,7 +2828,7 @@ static int stv090x_optimize_track(struct stv090x_state *state) | |||
2732 | s32 srate, pilots, aclc, f_1, f_0, i = 0, blind_tune = 0; | 2828 | s32 srate, pilots, aclc, f_1, f_0, i = 0, blind_tune = 0; |
2733 | u32 reg; | 2829 | u32 reg; |
2734 | 2830 | ||
2735 | srate = stv090x_get_srate(state, state->mclk); | 2831 | srate = stv090x_get_srate(state, state->internal->mclk); |
2736 | srate += stv090x_get_tmgoffst(state, srate); | 2832 | srate += stv090x_get_tmgoffst(state, srate); |
2737 | 2833 | ||
2738 | switch (state->delsys) { | 2834 | switch (state->delsys) { |
@@ -2751,7 +2847,7 @@ static int stv090x_optimize_track(struct stv090x_state *state) | |||
2751 | if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0) | 2847 | if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0) |
2752 | goto err; | 2848 | goto err; |
2753 | 2849 | ||
2754 | if (state->dev_ver >= 0x30) { | 2850 | if (state->internal->dev_ver >= 0x30) { |
2755 | if (stv090x_get_viterbi(state) < 0) | 2851 | if (stv090x_get_viterbi(state) < 0) |
2756 | goto err; | 2852 | goto err; |
2757 | 2853 | ||
@@ -2868,7 +2964,7 @@ static int stv090x_optimize_track(struct stv090x_state *state) | |||
2868 | goto err; | 2964 | goto err; |
2869 | } | 2965 | } |
2870 | 2966 | ||
2871 | if (state->dev_ver >= 0x20) { | 2967 | if (state->internal->dev_ver >= 0x20) { |
2872 | if ((state->search_mode == STV090x_SEARCH_DVBS1) || | 2968 | if ((state->search_mode == STV090x_SEARCH_DVBS1) || |
2873 | (state->search_mode == STV090x_SEARCH_DSS) || | 2969 | (state->search_mode == STV090x_SEARCH_DSS) || |
2874 | (state->search_mode == STV090x_SEARCH_AUTO)) { | 2970 | (state->search_mode == STV090x_SEARCH_AUTO)) { |
@@ -2890,7 +2986,8 @@ static int stv090x_optimize_track(struct stv090x_state *state) | |||
2890 | if (STV090x_WRITE_DEMOD(state, SFRLOW1, 0x80) < 0) | 2986 | if (STV090x_WRITE_DEMOD(state, SFRLOW1, 0x80) < 0) |
2891 | goto err; | 2987 | goto err; |
2892 | 2988 | ||
2893 | if ((state->dev_ver >= 0x20) || (blind_tune == 1) || (state->srate < 10000000)) { | 2989 | if ((state->internal->dev_ver >= 0x20) || (blind_tune == 1) || |
2990 | (state->srate < 10000000)) { | ||
2894 | /* update initial carrier freq with the found freq offset */ | 2991 | /* update initial carrier freq with the found freq offset */ |
2895 | if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0) | 2992 | if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0) |
2896 | goto err; | 2993 | goto err; |
@@ -2898,7 +2995,7 @@ static int stv090x_optimize_track(struct stv090x_state *state) | |||
2898 | goto err; | 2995 | goto err; |
2899 | state->tuner_bw = stv090x_car_width(srate, state->rolloff) + 10000000; | 2996 | state->tuner_bw = stv090x_car_width(srate, state->rolloff) + 10000000; |
2900 | 2997 | ||
2901 | if ((state->dev_ver >= 0x20) || (blind_tune == 1)) { | 2998 | if ((state->internal->dev_ver >= 0x20) || (blind_tune == 1)) { |
2902 | 2999 | ||
2903 | if (state->algo != STV090x_WARM_SEARCH) { | 3000 | if (state->algo != STV090x_WARM_SEARCH) { |
2904 | 3001 | ||
@@ -2907,7 +3004,7 @@ static int stv090x_optimize_track(struct stv090x_state *state) | |||
2907 | 3004 | ||
2908 | if (state->config->tuner_set_bandwidth) { | 3005 | if (state->config->tuner_set_bandwidth) { |
2909 | if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0) | 3006 | if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0) |
2910 | goto err; | 3007 | goto err_gateoff; |
2911 | } | 3008 | } |
2912 | 3009 | ||
2913 | if (stv090x_i2c_gate_ctrl(fe, 0) < 0) | 3010 | if (stv090x_i2c_gate_ctrl(fe, 0) < 0) |
@@ -2950,7 +3047,7 @@ static int stv090x_optimize_track(struct stv090x_state *state) | |||
2950 | 3047 | ||
2951 | } | 3048 | } |
2952 | 3049 | ||
2953 | if (state->dev_ver >= 0x20) { | 3050 | if (state->internal->dev_ver >= 0x20) { |
2954 | if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0) | 3051 | if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0) |
2955 | goto err; | 3052 | goto err; |
2956 | } | 3053 | } |
@@ -2959,6 +3056,9 @@ static int stv090x_optimize_track(struct stv090x_state *state) | |||
2959 | stv090x_set_vit_thtracq(state); | 3056 | stv090x_set_vit_thtracq(state); |
2960 | 3057 | ||
2961 | return 0; | 3058 | return 0; |
3059 | |||
3060 | err_gateoff: | ||
3061 | stv090x_i2c_gate_ctrl(fe, 0); | ||
2962 | err: | 3062 | err: |
2963 | dprintk(FE_ERROR, 1, "I/O error"); | 3063 | dprintk(FE_ERROR, 1, "I/O error"); |
2964 | return -1; | 3064 | return -1; |
@@ -3026,7 +3126,7 @@ static int stv090x_set_s2rolloff(struct stv090x_state *state) | |||
3026 | { | 3126 | { |
3027 | u32 reg; | 3127 | u32 reg; |
3028 | 3128 | ||
3029 | if (state->dev_ver <= 0x20) { | 3129 | if (state->internal->dev_ver <= 0x20) { |
3030 | /* rolloff to auto mode if DVBS2 */ | 3130 | /* rolloff to auto mode if DVBS2 */ |
3031 | reg = STV090x_READ_DEMOD(state, DEMOD); | 3131 | reg = STV090x_READ_DEMOD(state, DEMOD); |
3032 | STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 0x00); | 3132 | STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 0x00); |
@@ -3062,7 +3162,7 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) | |||
3062 | if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Demod stop */ | 3162 | if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Demod stop */ |
3063 | goto err; | 3163 | goto err; |
3064 | 3164 | ||
3065 | if (state->dev_ver >= 0x20) { | 3165 | if (state->internal->dev_ver >= 0x20) { |
3066 | if (state->srate > 5000000) { | 3166 | if (state->srate > 5000000) { |
3067 | if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0) | 3167 | if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0) |
3068 | goto err; | 3168 | goto err; |
@@ -3102,7 +3202,7 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) | |||
3102 | if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0) | 3202 | if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0) |
3103 | goto err; | 3203 | goto err; |
3104 | 3204 | ||
3105 | if (state->dev_ver >= 0x20) { | 3205 | if (state->internal->dev_ver >= 0x20) { |
3106 | if (STV090x_WRITE_DEMOD(state, KREFTMG, 0x5a) < 0) | 3206 | if (STV090x_WRITE_DEMOD(state, KREFTMG, 0x5a) < 0) |
3107 | goto err; | 3207 | goto err; |
3108 | if (state->algo == STV090x_COLD_SEARCH) | 3208 | if (state->algo == STV090x_COLD_SEARCH) |
@@ -3120,9 +3220,11 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) | |||
3120 | if (stv090x_set_srate(state, state->srate) < 0) | 3220 | if (stv090x_set_srate(state, state->srate) < 0) |
3121 | goto err; | 3221 | goto err; |
3122 | 3222 | ||
3123 | if (stv090x_set_max_srate(state, state->mclk, state->srate) < 0) | 3223 | if (stv090x_set_max_srate(state, state->internal->mclk, |
3224 | state->srate) < 0) | ||
3124 | goto err; | 3225 | goto err; |
3125 | if (stv090x_set_min_srate(state, state->mclk, state->srate) < 0) | 3226 | if (stv090x_set_min_srate(state, state->internal->mclk, |
3227 | state->srate) < 0) | ||
3126 | goto err; | 3228 | goto err; |
3127 | 3229 | ||
3128 | if (state->srate >= 10000000) | 3230 | if (state->srate >= 10000000) |
@@ -3136,18 +3238,21 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) | |||
3136 | goto err; | 3238 | goto err; |
3137 | 3239 | ||
3138 | if (state->config->tuner_set_bbgain) { | 3240 | if (state->config->tuner_set_bbgain) { |
3139 | if (state->config->tuner_set_bbgain(fe, 10) < 0) /* 10dB */ | 3241 | reg = state->config->tuner_bbgain; |
3140 | goto err; | 3242 | if (reg == 0) |
3243 | reg = 10; /* default: 10dB */ | ||
3244 | if (state->config->tuner_set_bbgain(fe, reg) < 0) | ||
3245 | goto err_gateoff; | ||
3141 | } | 3246 | } |
3142 | 3247 | ||
3143 | if (state->config->tuner_set_frequency) { | 3248 | if (state->config->tuner_set_frequency) { |
3144 | if (state->config->tuner_set_frequency(fe, state->frequency) < 0) | 3249 | if (state->config->tuner_set_frequency(fe, state->frequency) < 0) |
3145 | goto err; | 3250 | goto err_gateoff; |
3146 | } | 3251 | } |
3147 | 3252 | ||
3148 | if (state->config->tuner_set_bandwidth) { | 3253 | if (state->config->tuner_set_bandwidth) { |
3149 | if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0) | 3254 | if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0) |
3150 | goto err; | 3255 | goto err_gateoff; |
3151 | } | 3256 | } |
3152 | 3257 | ||
3153 | if (stv090x_i2c_gate_ctrl(fe, 0) < 0) | 3258 | if (stv090x_i2c_gate_ctrl(fe, 0) < 0) |
@@ -3155,21 +3260,21 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) | |||
3155 | 3260 | ||
3156 | msleep(50); | 3261 | msleep(50); |
3157 | 3262 | ||
3158 | if (stv090x_i2c_gate_ctrl(fe, 1) < 0) | ||
3159 | goto err; | ||
3160 | |||
3161 | if (state->config->tuner_get_status) { | 3263 | if (state->config->tuner_get_status) { |
3264 | if (stv090x_i2c_gate_ctrl(fe, 1) < 0) | ||
3265 | goto err; | ||
3162 | if (state->config->tuner_get_status(fe, ®) < 0) | 3266 | if (state->config->tuner_get_status(fe, ®) < 0) |
3267 | goto err_gateoff; | ||
3268 | if (stv090x_i2c_gate_ctrl(fe, 0) < 0) | ||
3163 | goto err; | 3269 | goto err; |
3164 | } | ||
3165 | 3270 | ||
3166 | if (reg) | 3271 | if (reg) |
3167 | dprintk(FE_DEBUG, 1, "Tuner phase locked"); | 3272 | dprintk(FE_DEBUG, 1, "Tuner phase locked"); |
3168 | else | 3273 | else { |
3169 | dprintk(FE_DEBUG, 1, "Tuner unlocked"); | 3274 | dprintk(FE_DEBUG, 1, "Tuner unlocked"); |
3170 | 3275 | return STV090x_NOCARRIER; | |
3171 | if (stv090x_i2c_gate_ctrl(fe, 0) < 0) | 3276 | } |
3172 | goto err; | 3277 | } |
3173 | 3278 | ||
3174 | msleep(10); | 3279 | msleep(10); |
3175 | agc1_power = MAKEWORD16(STV090x_READ_DEMOD(state, AGCIQIN1), | 3280 | agc1_power = MAKEWORD16(STV090x_READ_DEMOD(state, AGCIQIN1), |
@@ -3194,7 +3299,7 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) | |||
3194 | reg = STV090x_READ_DEMOD(state, DEMOD); | 3299 | reg = STV090x_READ_DEMOD(state, DEMOD); |
3195 | STV090x_SETFIELD_Px(reg, SPECINV_CONTROL_FIELD, state->inversion); | 3300 | STV090x_SETFIELD_Px(reg, SPECINV_CONTROL_FIELD, state->inversion); |
3196 | 3301 | ||
3197 | if (state->dev_ver <= 0x20) { | 3302 | if (state->internal->dev_ver <= 0x20) { |
3198 | /* rolloff to auto mode if DVBS2 */ | 3303 | /* rolloff to auto mode if DVBS2 */ |
3199 | STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 1); | 3304 | STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 1); |
3200 | } else { | 3305 | } else { |
@@ -3238,7 +3343,7 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) | |||
3238 | if ((lock) && (signal_state == STV090x_RANGEOK)) { /* signal within Range */ | 3343 | if ((lock) && (signal_state == STV090x_RANGEOK)) { /* signal within Range */ |
3239 | stv090x_optimize_track(state); | 3344 | stv090x_optimize_track(state); |
3240 | 3345 | ||
3241 | if (state->dev_ver >= 0x20) { | 3346 | if (state->internal->dev_ver >= 0x20) { |
3242 | /* >= Cut 2.0 :release TS reset after | 3347 | /* >= Cut 2.0 :release TS reset after |
3243 | * demod lock and optimized Tracking | 3348 | * demod lock and optimized Tracking |
3244 | */ | 3349 | */ |
@@ -3293,6 +3398,8 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state) | |||
3293 | } | 3398 | } |
3294 | return signal_state; | 3399 | return signal_state; |
3295 | 3400 | ||
3401 | err_gateoff: | ||
3402 | stv090x_i2c_gate_ctrl(fe, 0); | ||
3296 | err: | 3403 | err: |
3297 | dprintk(FE_ERROR, 1, "I/O error"); | 3404 | dprintk(FE_ERROR, 1, "I/O error"); |
3298 | return -1; | 3405 | return -1; |
@@ -3303,6 +3410,9 @@ static enum dvbfe_search stv090x_search(struct dvb_frontend *fe, struct dvb_fron | |||
3303 | struct stv090x_state *state = fe->demodulator_priv; | 3410 | struct stv090x_state *state = fe->demodulator_priv; |
3304 | struct dtv_frontend_properties *props = &fe->dtv_property_cache; | 3411 | struct dtv_frontend_properties *props = &fe->dtv_property_cache; |
3305 | 3412 | ||
3413 | if (p->frequency == 0) | ||
3414 | return DVBFE_ALGO_SEARCH_INVALID; | ||
3415 | |||
3306 | state->delsys = props->delivery_system; | 3416 | state->delsys = props->delivery_system; |
3307 | state->frequency = p->frequency; | 3417 | state->frequency = p->frequency; |
3308 | state->srate = p->u.qpsk.symbol_rate; | 3418 | state->srate = p->u.qpsk.symbol_rate; |
@@ -3353,7 +3463,8 @@ static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status) | |||
3353 | if (STV090x_GETFIELD_Px(reg, PKTDELIN_LOCK_FIELD)) { | 3463 | if (STV090x_GETFIELD_Px(reg, PKTDELIN_LOCK_FIELD)) { |
3354 | reg = STV090x_READ_DEMOD(state, TSSTATUS); | 3464 | reg = STV090x_READ_DEMOD(state, TSSTATUS); |
3355 | if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) { | 3465 | if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) { |
3356 | *status = FE_HAS_CARRIER | | 3466 | *status = FE_HAS_SIGNAL | |
3467 | FE_HAS_CARRIER | | ||
3357 | FE_HAS_VITERBI | | 3468 | FE_HAS_VITERBI | |
3358 | FE_HAS_SYNC | | 3469 | FE_HAS_SYNC | |
3359 | FE_HAS_LOCK; | 3470 | FE_HAS_LOCK; |
@@ -3370,7 +3481,11 @@ static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status) | |||
3370 | if (STV090x_GETFIELD_Px(reg, LOCKEDVIT_FIELD)) { | 3481 | if (STV090x_GETFIELD_Px(reg, LOCKEDVIT_FIELD)) { |
3371 | reg = STV090x_READ_DEMOD(state, TSSTATUS); | 3482 | reg = STV090x_READ_DEMOD(state, TSSTATUS); |
3372 | if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) { | 3483 | if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) { |
3373 | *status = FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; | 3484 | *status = FE_HAS_SIGNAL | |
3485 | FE_HAS_CARRIER | | ||
3486 | FE_HAS_VITERBI | | ||
3487 | FE_HAS_SYNC | | ||
3488 | FE_HAS_LOCK; | ||
3374 | } | 3489 | } |
3375 | } | 3490 | } |
3376 | } | 3491 | } |
@@ -3770,6 +3885,15 @@ static void stv090x_release(struct dvb_frontend *fe) | |||
3770 | { | 3885 | { |
3771 | struct stv090x_state *state = fe->demodulator_priv; | 3886 | struct stv090x_state *state = fe->demodulator_priv; |
3772 | 3887 | ||
3888 | state->internal->num_used--; | ||
3889 | if (state->internal->num_used <= 0) { | ||
3890 | |||
3891 | dprintk(FE_ERROR, 1, "Actually removing"); | ||
3892 | |||
3893 | remove_dev(state->internal); | ||
3894 | kfree(state->internal); | ||
3895 | } | ||
3896 | |||
3773 | kfree(state); | 3897 | kfree(state); |
3774 | } | 3898 | } |
3775 | 3899 | ||
@@ -3901,10 +4025,10 @@ static int stv090x_set_mclk(struct stv090x_state *state, u32 mclk, u32 clk) | |||
3901 | if (stv090x_write_reg(state, STV090x_NCOARSE, reg) < 0) | 4025 | if (stv090x_write_reg(state, STV090x_NCOARSE, reg) < 0) |
3902 | goto err; | 4026 | goto err; |
3903 | 4027 | ||
3904 | state->mclk = stv090x_get_mclk(state); | 4028 | state->internal->mclk = stv090x_get_mclk(state); |
3905 | 4029 | ||
3906 | /*Set the DiseqC frequency to 22KHz */ | 4030 | /*Set the DiseqC frequency to 22KHz */ |
3907 | div = state->mclk / 704000; | 4031 | div = state->internal->mclk / 704000; |
3908 | if (STV090x_WRITE_DEMOD(state, F22TX, div) < 0) | 4032 | if (STV090x_WRITE_DEMOD(state, F22TX, div) < 0) |
3909 | goto err; | 4033 | goto err; |
3910 | if (STV090x_WRITE_DEMOD(state, F22RX, div) < 0) | 4034 | if (STV090x_WRITE_DEMOD(state, F22RX, div) < 0) |
@@ -3920,7 +4044,7 @@ static int stv090x_set_tspath(struct stv090x_state *state) | |||
3920 | { | 4044 | { |
3921 | u32 reg; | 4045 | u32 reg; |
3922 | 4046 | ||
3923 | if (state->dev_ver >= 0x20) { | 4047 | if (state->internal->dev_ver >= 0x20) { |
3924 | switch (state->config->ts1_mode) { | 4048 | switch (state->config->ts1_mode) { |
3925 | case STV090x_TSMODE_PARALLEL_PUNCTURED: | 4049 | case STV090x_TSMODE_PARALLEL_PUNCTURED: |
3926 | case STV090x_TSMODE_DVBCI: | 4050 | case STV090x_TSMODE_DVBCI: |
@@ -4092,6 +4216,71 @@ static int stv090x_set_tspath(struct stv090x_state *state) | |||
4092 | default: | 4216 | default: |
4093 | break; | 4217 | break; |
4094 | } | 4218 | } |
4219 | |||
4220 | if (state->config->ts1_clk > 0) { | ||
4221 | u32 speed; | ||
4222 | |||
4223 | switch (state->config->ts1_mode) { | ||
4224 | case STV090x_TSMODE_PARALLEL_PUNCTURED: | ||
4225 | case STV090x_TSMODE_DVBCI: | ||
4226 | default: | ||
4227 | speed = state->internal->mclk / | ||
4228 | (state->config->ts1_clk / 4); | ||
4229 | if (speed < 0x08) | ||
4230 | speed = 0x08; | ||
4231 | if (speed > 0xFF) | ||
4232 | speed = 0xFF; | ||
4233 | break; | ||
4234 | case STV090x_TSMODE_SERIAL_PUNCTURED: | ||
4235 | case STV090x_TSMODE_SERIAL_CONTINUOUS: | ||
4236 | speed = state->internal->mclk / | ||
4237 | (state->config->ts1_clk / 32); | ||
4238 | if (speed < 0x20) | ||
4239 | speed = 0x20; | ||
4240 | if (speed > 0xFF) | ||
4241 | speed = 0xFF; | ||
4242 | break; | ||
4243 | } | ||
4244 | reg = stv090x_read_reg(state, STV090x_P1_TSCFGM); | ||
4245 | STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3); | ||
4246 | if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0) | ||
4247 | goto err; | ||
4248 | if (stv090x_write_reg(state, STV090x_P1_TSSPEED, speed) < 0) | ||
4249 | goto err; | ||
4250 | } | ||
4251 | |||
4252 | if (state->config->ts2_clk > 0) { | ||
4253 | u32 speed; | ||
4254 | |||
4255 | switch (state->config->ts2_mode) { | ||
4256 | case STV090x_TSMODE_PARALLEL_PUNCTURED: | ||
4257 | case STV090x_TSMODE_DVBCI: | ||
4258 | default: | ||
4259 | speed = state->internal->mclk / | ||
4260 | (state->config->ts2_clk / 4); | ||
4261 | if (speed < 0x08) | ||
4262 | speed = 0x08; | ||
4263 | if (speed > 0xFF) | ||
4264 | speed = 0xFF; | ||
4265 | break; | ||
4266 | case STV090x_TSMODE_SERIAL_PUNCTURED: | ||
4267 | case STV090x_TSMODE_SERIAL_CONTINUOUS: | ||
4268 | speed = state->internal->mclk / | ||
4269 | (state->config->ts2_clk / 32); | ||
4270 | if (speed < 0x20) | ||
4271 | speed = 0x20; | ||
4272 | if (speed > 0xFF) | ||
4273 | speed = 0xFF; | ||
4274 | break; | ||
4275 | } | ||
4276 | reg = stv090x_read_reg(state, STV090x_P2_TSCFGM); | ||
4277 | STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3); | ||
4278 | if (stv090x_write_reg(state, STV090x_P2_TSCFGM, reg) < 0) | ||
4279 | goto err; | ||
4280 | if (stv090x_write_reg(state, STV090x_P2_TSSPEED, speed) < 0) | ||
4281 | goto err; | ||
4282 | } | ||
4283 | |||
4095 | reg = stv090x_read_reg(state, STV090x_P2_TSCFGH); | 4284 | reg = stv090x_read_reg(state, STV090x_P2_TSCFGH); |
4096 | STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x01); | 4285 | STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x01); |
4097 | if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0) | 4286 | if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0) |
@@ -4120,6 +4309,15 @@ static int stv090x_init(struct dvb_frontend *fe) | |||
4120 | const struct stv090x_config *config = state->config; | 4309 | const struct stv090x_config *config = state->config; |
4121 | u32 reg; | 4310 | u32 reg; |
4122 | 4311 | ||
4312 | if (state->internal->mclk == 0) { | ||
4313 | stv090x_set_mclk(state, 135000000, config->xtal); /* 135 Mhz */ | ||
4314 | msleep(5); | ||
4315 | if (stv090x_write_reg(state, STV090x_SYNTCTRL, | ||
4316 | 0x20 | config->clk_mode) < 0) | ||
4317 | goto err; | ||
4318 | stv090x_get_mclk(state); | ||
4319 | } | ||
4320 | |||
4123 | if (stv090x_wakeup(fe) < 0) { | 4321 | if (stv090x_wakeup(fe) < 0) { |
4124 | dprintk(FE_ERROR, 1, "Error waking device"); | 4322 | dprintk(FE_ERROR, 1, "Error waking device"); |
4125 | goto err; | 4323 | goto err; |
@@ -4142,12 +4340,12 @@ static int stv090x_init(struct dvb_frontend *fe) | |||
4142 | 4340 | ||
4143 | if (config->tuner_set_mode) { | 4341 | if (config->tuner_set_mode) { |
4144 | if (config->tuner_set_mode(fe, TUNER_WAKE) < 0) | 4342 | if (config->tuner_set_mode(fe, TUNER_WAKE) < 0) |
4145 | goto err; | 4343 | goto err_gateoff; |
4146 | } | 4344 | } |
4147 | 4345 | ||
4148 | if (config->tuner_init) { | 4346 | if (config->tuner_init) { |
4149 | if (config->tuner_init(fe) < 0) | 4347 | if (config->tuner_init(fe) < 0) |
4150 | goto err; | 4348 | goto err_gateoff; |
4151 | } | 4349 | } |
4152 | 4350 | ||
4153 | if (stv090x_i2c_gate_ctrl(fe, 0) < 0) | 4351 | if (stv090x_i2c_gate_ctrl(fe, 0) < 0) |
@@ -4157,6 +4355,9 @@ static int stv090x_init(struct dvb_frontend *fe) | |||
4157 | goto err; | 4355 | goto err; |
4158 | 4356 | ||
4159 | return 0; | 4357 | return 0; |
4358 | |||
4359 | err_gateoff: | ||
4360 | stv090x_i2c_gate_ctrl(fe, 0); | ||
4160 | err: | 4361 | err: |
4161 | dprintk(FE_ERROR, 1, "I/O error"); | 4362 | dprintk(FE_ERROR, 1, "I/O error"); |
4162 | return -1; | 4363 | return -1; |
@@ -4188,16 +4389,26 @@ static int stv090x_setup(struct dvb_frontend *fe) | |||
4188 | } | 4389 | } |
4189 | 4390 | ||
4190 | /* STV090x init */ | 4391 | /* STV090x init */ |
4191 | if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Stop Demod */ | 4392 | |
4393 | /* Stop Demod */ | ||
4394 | if (stv090x_write_reg(state, STV090x_P1_DMDISTATE, 0x5c) < 0) | ||
4395 | goto err; | ||
4396 | if (stv090x_write_reg(state, STV090x_P2_DMDISTATE, 0x5c) < 0) | ||
4192 | goto err; | 4397 | goto err; |
4193 | 4398 | ||
4194 | msleep(5); | 4399 | msleep(5); |
4195 | 4400 | ||
4196 | if (STV090x_WRITE_DEMOD(state, TNRCFG, 0x6c) < 0) /* check register ! (No Tuner Mode) */ | 4401 | /* Set No Tuner Mode */ |
4402 | if (stv090x_write_reg(state, STV090x_P1_TNRCFG, 0x6c) < 0) | ||
4403 | goto err; | ||
4404 | if (stv090x_write_reg(state, STV090x_P2_TNRCFG, 0x6c) < 0) | ||
4197 | goto err; | 4405 | goto err; |
4198 | 4406 | ||
4407 | /* I2C repeater OFF */ | ||
4199 | STV090x_SETFIELD_Px(reg, ENARPT_LEVEL_FIELD, config->repeater_level); | 4408 | STV090x_SETFIELD_Px(reg, ENARPT_LEVEL_FIELD, config->repeater_level); |
4200 | if (STV090x_WRITE_DEMOD(state, I2CRPT, reg) < 0) /* repeater OFF */ | 4409 | if (stv090x_write_reg(state, STV090x_P1_I2CRPT, reg) < 0) |
4410 | goto err; | ||
4411 | if (stv090x_write_reg(state, STV090x_P2_I2CRPT, reg) < 0) | ||
4201 | goto err; | 4412 | goto err; |
4202 | 4413 | ||
4203 | if (stv090x_write_reg(state, STV090x_NCOARSE, 0x13) < 0) /* set PLL divider */ | 4414 | if (stv090x_write_reg(state, STV090x_NCOARSE, 0x13) < 0) /* set PLL divider */ |
@@ -4216,8 +4427,8 @@ static int stv090x_setup(struct dvb_frontend *fe) | |||
4216 | goto err; | 4427 | goto err; |
4217 | } | 4428 | } |
4218 | 4429 | ||
4219 | state->dev_ver = stv090x_read_reg(state, STV090x_MID); | 4430 | state->internal->dev_ver = stv090x_read_reg(state, STV090x_MID); |
4220 | if (state->dev_ver >= 0x20) { | 4431 | if (state->internal->dev_ver >= 0x20) { |
4221 | if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x0c) < 0) | 4432 | if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x0c) < 0) |
4222 | goto err; | 4433 | goto err; |
4223 | 4434 | ||
@@ -4228,27 +4439,35 @@ static int stv090x_setup(struct dvb_frontend *fe) | |||
4228 | goto err; | 4439 | goto err; |
4229 | } | 4440 | } |
4230 | 4441 | ||
4231 | } else if (state->dev_ver < 0x20) { | 4442 | } else if (state->internal->dev_ver < 0x20) { |
4232 | dprintk(FE_ERROR, 1, "ERROR: Unsupported Cut: 0x%02x!", | 4443 | dprintk(FE_ERROR, 1, "ERROR: Unsupported Cut: 0x%02x!", |
4233 | state->dev_ver); | 4444 | state->internal->dev_ver); |
4234 | 4445 | ||
4235 | goto err; | 4446 | goto err; |
4236 | } else if (state->dev_ver > 0x30) { | 4447 | } else if (state->internal->dev_ver > 0x30) { |
4237 | /* we shouldn't bail out from here */ | 4448 | /* we shouldn't bail out from here */ |
4238 | dprintk(FE_ERROR, 1, "INFO: Cut: 0x%02x probably incomplete support!", | 4449 | dprintk(FE_ERROR, 1, "INFO: Cut: 0x%02x probably incomplete support!", |
4239 | state->dev_ver); | 4450 | state->internal->dev_ver); |
4240 | } | 4451 | } |
4241 | 4452 | ||
4242 | if (stv090x_write_reg(state, STV090x_TSTRES0, 0x80) < 0) | 4453 | /* ADC1 range */ |
4454 | reg = stv090x_read_reg(state, STV090x_TSTTNR1); | ||
4455 | STV090x_SETFIELD(reg, ADC1_INMODE_FIELD, | ||
4456 | (config->adc1_range == STV090x_ADC_1Vpp) ? 0 : 1); | ||
4457 | if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0) | ||
4243 | goto err; | 4458 | goto err; |
4244 | if (stv090x_write_reg(state, STV090x_TSTRES0, 0x00) < 0) | 4459 | |
4460 | /* ADC2 range */ | ||
4461 | reg = stv090x_read_reg(state, STV090x_TSTTNR3); | ||
4462 | STV090x_SETFIELD(reg, ADC2_INMODE_FIELD, | ||
4463 | (config->adc2_range == STV090x_ADC_1Vpp) ? 0 : 1); | ||
4464 | if (stv090x_write_reg(state, STV090x_TSTTNR3, reg) < 0) | ||
4245 | goto err; | 4465 | goto err; |
4246 | 4466 | ||
4247 | stv090x_set_mclk(state, 135000000, config->xtal); /* 135 Mhz */ | 4467 | if (stv090x_write_reg(state, STV090x_TSTRES0, 0x80) < 0) |
4248 | msleep(5); | 4468 | goto err; |
4249 | if (stv090x_write_reg(state, STV090x_SYNTCTRL, 0x20 | config->clk_mode) < 0) | 4469 | if (stv090x_write_reg(state, STV090x_TSTRES0, 0x00) < 0) |
4250 | goto err; | 4470 | goto err; |
4251 | stv090x_get_mclk(state); | ||
4252 | 4471 | ||
4253 | return 0; | 4472 | return 0; |
4254 | err: | 4473 | err: |
@@ -4299,6 +4518,7 @@ struct dvb_frontend *stv090x_attach(const struct stv090x_config *config, | |||
4299 | enum stv090x_demodulator demod) | 4518 | enum stv090x_demodulator demod) |
4300 | { | 4519 | { |
4301 | struct stv090x_state *state = NULL; | 4520 | struct stv090x_state *state = NULL; |
4521 | struct stv090x_dev *temp_int; | ||
4302 | 4522 | ||
4303 | state = kzalloc(sizeof (struct stv090x_state), GFP_KERNEL); | 4523 | state = kzalloc(sizeof (struct stv090x_state), GFP_KERNEL); |
4304 | if (state == NULL) | 4524 | if (state == NULL) |
@@ -4314,8 +4534,32 @@ struct dvb_frontend *stv090x_attach(const struct stv090x_config *config, | |||
4314 | state->device = config->device; | 4534 | state->device = config->device; |
4315 | state->rolloff = STV090x_RO_35; /* default */ | 4535 | state->rolloff = STV090x_RO_35; /* default */ |
4316 | 4536 | ||
4317 | if (state->demod == STV090x_DEMODULATOR_0) | 4537 | temp_int = find_dev(state->i2c, |
4318 | mutex_init(&demod_lock); | 4538 | state->config->address); |
4539 | |||
4540 | if ((temp_int != NULL) && (state->demod_mode == STV090x_DUAL)) { | ||
4541 | state->internal = temp_int->internal; | ||
4542 | state->internal->num_used++; | ||
4543 | dprintk(FE_INFO, 1, "Found Internal Structure!"); | ||
4544 | dprintk(FE_ERROR, 1, "Attaching %s demodulator(%d) Cut=0x%02x", | ||
4545 | state->device == STV0900 ? "STV0900" : "STV0903", | ||
4546 | demod, | ||
4547 | state->internal->dev_ver); | ||
4548 | return &state->frontend; | ||
4549 | } else { | ||
4550 | state->internal = kmalloc(sizeof(struct stv090x_internal), | ||
4551 | GFP_KERNEL); | ||
4552 | temp_int = append_internal(state->internal); | ||
4553 | state->internal->num_used = 1; | ||
4554 | state->internal->mclk = 0; | ||
4555 | state->internal->dev_ver = 0; | ||
4556 | state->internal->i2c_adap = state->i2c; | ||
4557 | state->internal->i2c_addr = state->config->address; | ||
4558 | dprintk(FE_INFO, 1, "Create New Internal Structure!"); | ||
4559 | } | ||
4560 | |||
4561 | mutex_init(&state->internal->demod_lock); | ||
4562 | mutex_init(&state->internal->tuner_lock); | ||
4319 | 4563 | ||
4320 | if (stv090x_sleep(&state->frontend) < 0) { | 4564 | if (stv090x_sleep(&state->frontend) < 0) { |
4321 | dprintk(FE_ERROR, 1, "Error putting device to sleep"); | 4565 | dprintk(FE_ERROR, 1, "Error putting device to sleep"); |
@@ -4331,10 +4575,10 @@ struct dvb_frontend *stv090x_attach(const struct stv090x_config *config, | |||
4331 | goto error; | 4575 | goto error; |
4332 | } | 4576 | } |
4333 | 4577 | ||
4334 | dprintk(FE_ERROR, 1, "Attaching %s demodulator(%d) Cut=0x%02x\n", | 4578 | dprintk(FE_ERROR, 1, "Attaching %s demodulator(%d) Cut=0x%02x", |
4335 | state->device == STV0900 ? "STV0900" : "STV0903", | 4579 | state->device == STV0900 ? "STV0900" : "STV0903", |
4336 | demod, | 4580 | demod, |
4337 | state->dev_ver); | 4581 | state->internal->dev_ver); |
4338 | 4582 | ||
4339 | return &state->frontend; | 4583 | return &state->frontend; |
4340 | 4584 | ||
diff --git a/drivers/media/dvb/frontends/stv090x.h b/drivers/media/dvb/frontends/stv090x.h index b133807663ea..30f01a6902ac 100644 --- a/drivers/media/dvb/frontends/stv090x.h +++ b/drivers/media/dvb/frontends/stv090x.h | |||
@@ -60,6 +60,11 @@ enum stv090x_i2crpt { | |||
60 | STV090x_RPTLEVEL_2 = 7, | 60 | STV090x_RPTLEVEL_2 = 7, |
61 | }; | 61 | }; |
62 | 62 | ||
63 | enum stv090x_adc_range { | ||
64 | STV090x_ADC_2Vpp = 0, | ||
65 | STV090x_ADC_1Vpp = 1 | ||
66 | }; | ||
67 | |||
63 | struct stv090x_config { | 68 | struct stv090x_config { |
64 | enum stv090x_device device; | 69 | enum stv090x_device device; |
65 | enum stv090x_mode demod_mode; | 70 | enum stv090x_mode demod_mode; |
@@ -68,13 +73,17 @@ struct stv090x_config { | |||
68 | u32 xtal; /* default: 8000000 */ | 73 | u32 xtal; /* default: 8000000 */ |
69 | u8 address; /* default: 0x68 */ | 74 | u8 address; /* default: 0x68 */ |
70 | 75 | ||
71 | u32 ref_clk; /* default: 16000000 FIXME to tuner config */ | ||
72 | |||
73 | u8 ts1_mode; | 76 | u8 ts1_mode; |
74 | u8 ts2_mode; | 77 | u8 ts2_mode; |
78 | u32 ts1_clk; | ||
79 | u32 ts2_clk; | ||
75 | 80 | ||
76 | enum stv090x_i2crpt repeater_level; | 81 | enum stv090x_i2crpt repeater_level; |
77 | 82 | ||
83 | u8 tuner_bbgain; /* default: 10db */ | ||
84 | enum stv090x_adc_range adc1_range; /* default: 2Vpp */ | ||
85 | enum stv090x_adc_range adc2_range; /* default: 2Vpp */ | ||
86 | |||
78 | bool diseqc_envelope_mode; | 87 | bool diseqc_envelope_mode; |
79 | 88 | ||
80 | int (*tuner_init) (struct dvb_frontend *fe); | 89 | int (*tuner_init) (struct dvb_frontend *fe); |
diff --git a/drivers/media/dvb/frontends/stv090x_priv.h b/drivers/media/dvb/frontends/stv090x_priv.h index 5921a8d6c89f..5b780c80d496 100644 --- a/drivers/media/dvb/frontends/stv090x_priv.h +++ b/drivers/media/dvb/frontends/stv090x_priv.h | |||
@@ -230,11 +230,23 @@ struct stv090x_tab { | |||
230 | s32 read; | 230 | s32 read; |
231 | }; | 231 | }; |
232 | 232 | ||
233 | struct stv090x_internal { | ||
234 | struct i2c_adapter *i2c_adap; | ||
235 | u8 i2c_addr; | ||
236 | |||
237 | struct mutex demod_lock; /* Lock access to shared register */ | ||
238 | struct mutex tuner_lock; /* Lock access to tuners */ | ||
239 | s32 mclk; /* Masterclock Divider factor */ | ||
240 | u32 dev_ver; | ||
241 | |||
242 | int num_used; | ||
243 | }; | ||
244 | |||
233 | struct stv090x_state { | 245 | struct stv090x_state { |
234 | enum stv090x_device device; | 246 | enum stv090x_device device; |
235 | enum stv090x_demodulator demod; | 247 | enum stv090x_demodulator demod; |
236 | enum stv090x_mode demod_mode; | 248 | enum stv090x_mode demod_mode; |
237 | u32 dev_ver; | 249 | struct stv090x_internal *internal; |
238 | 250 | ||
239 | struct i2c_adapter *i2c; | 251 | struct i2c_adapter *i2c; |
240 | const struct stv090x_config *config; | 252 | const struct stv090x_config *config; |
@@ -256,11 +268,8 @@ struct stv090x_state { | |||
256 | u32 frequency; | 268 | u32 frequency; |
257 | u32 srate; | 269 | u32 srate; |
258 | 270 | ||
259 | s32 mclk; /* Masterclock Divider factor */ | ||
260 | s32 tuner_bw; | 271 | s32 tuner_bw; |
261 | 272 | ||
262 | u32 tuner_refclk; | ||
263 | |||
264 | s32 search_range; | 273 | s32 search_range; |
265 | 274 | ||
266 | s32 DemodTimeout; | 275 | s32 DemodTimeout; |
diff --git a/drivers/media/dvb/frontends/stv6110x.c b/drivers/media/dvb/frontends/stv6110x.c index bcfcb652464c..f931ed07e92d 100644 --- a/drivers/media/dvb/frontends/stv6110x.c +++ b/drivers/media/dvb/frontends/stv6110x.c | |||
@@ -35,8 +35,6 @@ static unsigned int verbose; | |||
35 | module_param(verbose, int, 0644); | 35 | module_param(verbose, int, 0644); |
36 | MODULE_PARM_DESC(verbose, "Set Verbosity level"); | 36 | MODULE_PARM_DESC(verbose, "Set Verbosity level"); |
37 | 37 | ||
38 | static u8 stv6110x_regs[] = {0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e}; | ||
39 | |||
40 | static int stv6110x_read_reg(struct stv6110x_state *stv6110x, u8 reg, u8 *data) | 38 | static int stv6110x_read_reg(struct stv6110x_state *stv6110x, u8 reg, u8 *data) |
41 | { | 39 | { |
42 | int ret; | 40 | int ret; |
@@ -58,12 +56,23 @@ static int stv6110x_read_reg(struct stv6110x_state *stv6110x, u8 reg, u8 *data) | |||
58 | return 0; | 56 | return 0; |
59 | } | 57 | } |
60 | 58 | ||
61 | static int stv6110x_write_reg(struct stv6110x_state *stv6110x, u8 reg, u8 data) | 59 | static int stv6110x_write_regs(struct stv6110x_state *stv6110x, int start, u8 data[], int len) |
62 | { | 60 | { |
63 | int ret; | 61 | int ret; |
64 | const struct stv6110x_config *config = stv6110x->config; | 62 | const struct stv6110x_config *config = stv6110x->config; |
65 | u8 buf[] = { reg, data }; | 63 | u8 buf[len + 1]; |
66 | struct i2c_msg msg = { .addr = config->addr, .flags = 0, . buf = buf, .len = 2 }; | 64 | struct i2c_msg msg = { |
65 | .addr = config->addr, | ||
66 | .flags = 0, | ||
67 | .buf = buf, | ||
68 | .len = len + 1 | ||
69 | }; | ||
70 | |||
71 | if (start + len > 8) | ||
72 | return -EINVAL; | ||
73 | |||
74 | buf[0] = start; | ||
75 | memcpy(&buf[1], data, len); | ||
67 | 76 | ||
68 | ret = i2c_transfer(stv6110x->i2c, &msg, 1); | 77 | ret = i2c_transfer(stv6110x->i2c, &msg, 1); |
69 | if (ret != 1) { | 78 | if (ret != 1) { |
@@ -74,18 +83,21 @@ static int stv6110x_write_reg(struct stv6110x_state *stv6110x, u8 reg, u8 data) | |||
74 | return 0; | 83 | return 0; |
75 | } | 84 | } |
76 | 85 | ||
86 | static int stv6110x_write_reg(struct stv6110x_state *stv6110x, u8 reg, u8 data) | ||
87 | { | ||
88 | return stv6110x_write_regs(stv6110x, reg, &data, 1); | ||
89 | } | ||
90 | |||
77 | static int stv6110x_init(struct dvb_frontend *fe) | 91 | static int stv6110x_init(struct dvb_frontend *fe) |
78 | { | 92 | { |
79 | struct stv6110x_state *stv6110x = fe->tuner_priv; | 93 | struct stv6110x_state *stv6110x = fe->tuner_priv; |
80 | int ret; | 94 | int ret; |
81 | u8 i; | ||
82 | 95 | ||
83 | for (i = 0; i < ARRAY_SIZE(stv6110x_regs); i++) { | 96 | ret = stv6110x_write_regs(stv6110x, 0, stv6110x->regs, |
84 | ret = stv6110x_write_reg(stv6110x, i, stv6110x_regs[i]); | 97 | ARRAY_SIZE(stv6110x->regs)); |
85 | if (ret < 0) { | 98 | if (ret < 0) { |
86 | dprintk(FE_ERROR, 1, "Initialization failed"); | 99 | dprintk(FE_ERROR, 1, "Initialization failed"); |
87 | return -1; | 100 | return -1; |
88 | } | ||
89 | } | 101 | } |
90 | 102 | ||
91 | return 0; | 103 | return 0; |
@@ -98,23 +110,23 @@ static int stv6110x_set_frequency(struct dvb_frontend *fe, u32 frequency) | |||
98 | s32 pVal, pCalc, rDivOpt = 0, pCalcOpt = 1000; | 110 | s32 pVal, pCalc, rDivOpt = 0, pCalcOpt = 1000; |
99 | u8 i; | 111 | u8 i; |
100 | 112 | ||
101 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_K, (REFCLOCK_MHz - 16)); | 113 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_K, (REFCLOCK_MHz - 16)); |
102 | 114 | ||
103 | if (frequency <= 1023000) { | 115 | if (frequency <= 1023000) { |
104 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_DIV4SEL, 1); | 116 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 1); |
105 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0); | 117 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0); |
106 | pVal = 40; | 118 | pVal = 40; |
107 | } else if (frequency <= 1300000) { | 119 | } else if (frequency <= 1300000) { |
108 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_DIV4SEL, 1); | 120 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 1); |
109 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1); | 121 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1); |
110 | pVal = 40; | 122 | pVal = 40; |
111 | } else if (frequency <= 2046000) { | 123 | } else if (frequency <= 2046000) { |
112 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_DIV4SEL, 0); | 124 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 0); |
113 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0); | 125 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0); |
114 | pVal = 20; | 126 | pVal = 20; |
115 | } else { | 127 | } else { |
116 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_DIV4SEL, 0); | 128 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 0); |
117 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1); | 129 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1); |
118 | pVal = 20; | 130 | pVal = 20; |
119 | } | 131 | } |
120 | 132 | ||
@@ -130,21 +142,21 @@ static int stv6110x_set_frequency(struct dvb_frontend *fe, u32 frequency) | |||
130 | divider = (frequency * R_DIV(rDivOpt) * pVal) / REFCLOCK_kHz; | 142 | divider = (frequency * R_DIV(rDivOpt) * pVal) / REFCLOCK_kHz; |
131 | divider = (divider + 5) / 10; | 143 | divider = (divider + 5) / 10; |
132 | 144 | ||
133 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_R_DIV, rDivOpt); | 145 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_R_DIV, rDivOpt); |
134 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_N_DIV_11_8, MSB(divider)); | 146 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_N_DIV_11_8, MSB(divider)); |
135 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG0], TNG0_N_DIV_7_0, LSB(divider)); | 147 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG0], TNG0_N_DIV_7_0, LSB(divider)); |
136 | 148 | ||
137 | /* VCO Auto calibration */ | 149 | /* VCO Auto calibration */ |
138 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_STAT1], STAT1_CALVCO_STRT, 1); | 150 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_STAT1], STAT1_CALVCO_STRT, 1); |
139 | 151 | ||
140 | stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x_regs[STV6110x_CTRL1]); | 152 | stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x->regs[STV6110x_CTRL1]); |
141 | stv6110x_write_reg(stv6110x, STV6110x_TNG1, stv6110x_regs[STV6110x_TNG1]); | 153 | stv6110x_write_reg(stv6110x, STV6110x_TNG1, stv6110x->regs[STV6110x_TNG1]); |
142 | stv6110x_write_reg(stv6110x, STV6110x_TNG0, stv6110x_regs[STV6110x_TNG0]); | 154 | stv6110x_write_reg(stv6110x, STV6110x_TNG0, stv6110x->regs[STV6110x_TNG0]); |
143 | stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x_regs[STV6110x_STAT1]); | 155 | stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x->regs[STV6110x_STAT1]); |
144 | 156 | ||
145 | for (i = 0; i < TRIALS; i++) { | 157 | for (i = 0; i < TRIALS; i++) { |
146 | stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x_regs[STV6110x_STAT1]); | 158 | stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x->regs[STV6110x_STAT1]); |
147 | if (!STV6110x_GETFIELD(STAT1_CALVCO_STRT, stv6110x_regs[STV6110x_STAT1])) | 159 | if (!STV6110x_GETFIELD(STAT1_CALVCO_STRT, stv6110x->regs[STV6110x_STAT1])) |
148 | break; | 160 | break; |
149 | msleep(1); | 161 | msleep(1); |
150 | } | 162 | } |
@@ -156,14 +168,14 @@ static int stv6110x_get_frequency(struct dvb_frontend *fe, u32 *frequency) | |||
156 | { | 168 | { |
157 | struct stv6110x_state *stv6110x = fe->tuner_priv; | 169 | struct stv6110x_state *stv6110x = fe->tuner_priv; |
158 | 170 | ||
159 | stv6110x_read_reg(stv6110x, STV6110x_TNG1, &stv6110x_regs[STV6110x_TNG1]); | 171 | stv6110x_read_reg(stv6110x, STV6110x_TNG1, &stv6110x->regs[STV6110x_TNG1]); |
160 | stv6110x_read_reg(stv6110x, STV6110x_TNG0, &stv6110x_regs[STV6110x_TNG0]); | 172 | stv6110x_read_reg(stv6110x, STV6110x_TNG0, &stv6110x->regs[STV6110x_TNG0]); |
161 | 173 | ||
162 | *frequency = (MAKEWORD16(STV6110x_GETFIELD(TNG1_N_DIV_11_8, stv6110x_regs[STV6110x_TNG1]), | 174 | *frequency = (MAKEWORD16(STV6110x_GETFIELD(TNG1_N_DIV_11_8, stv6110x->regs[STV6110x_TNG1]), |
163 | STV6110x_GETFIELD(TNG0_N_DIV_7_0, stv6110x_regs[STV6110x_TNG0]))) * REFCLOCK_kHz; | 175 | STV6110x_GETFIELD(TNG0_N_DIV_7_0, stv6110x->regs[STV6110x_TNG0]))) * REFCLOCK_kHz; |
164 | 176 | ||
165 | *frequency /= (1 << (STV6110x_GETFIELD(TNG1_R_DIV, stv6110x_regs[STV6110x_TNG1]) + | 177 | *frequency /= (1 << (STV6110x_GETFIELD(TNG1_R_DIV, stv6110x->regs[STV6110x_TNG1]) + |
166 | STV6110x_GETFIELD(TNG1_DIV4SEL, stv6110x_regs[STV6110x_TNG1]))); | 178 | STV6110x_GETFIELD(TNG1_DIV4SEL, stv6110x->regs[STV6110x_TNG1]))); |
167 | 179 | ||
168 | *frequency >>= 2; | 180 | *frequency >>= 2; |
169 | 181 | ||
@@ -179,27 +191,27 @@ static int stv6110x_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth) | |||
179 | halfbw = bandwidth >> 1; | 191 | halfbw = bandwidth >> 1; |
180 | 192 | ||
181 | if (halfbw > 36000000) | 193 | if (halfbw > 36000000) |
182 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_CF, 31); /* LPF */ | 194 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_CF, 31); /* LPF */ |
183 | else if (halfbw < 5000000) | 195 | else if (halfbw < 5000000) |
184 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_CF, 0); /* LPF */ | 196 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_CF, 0); /* LPF */ |
185 | else | 197 | else |
186 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_CF, ((halfbw / 1000000) - 5)); /* LPF */ | 198 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_CF, ((halfbw / 1000000) - 5)); /* LPF */ |
187 | 199 | ||
188 | 200 | ||
189 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x0); /* cal. clk activated */ | 201 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x0); /* cal. clk activated */ |
190 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_STAT1], STAT1_CALRC_STRT, 0x1); /* LPF auto cal */ | 202 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_STAT1], STAT1_CALRC_STRT, 0x1); /* LPF auto cal */ |
191 | 203 | ||
192 | stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x_regs[STV6110x_CTRL3]); | 204 | stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x->regs[STV6110x_CTRL3]); |
193 | stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x_regs[STV6110x_STAT1]); | 205 | stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x->regs[STV6110x_STAT1]); |
194 | 206 | ||
195 | for (i = 0; i < TRIALS; i++) { | 207 | for (i = 0; i < TRIALS; i++) { |
196 | stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x_regs[STV6110x_STAT1]); | 208 | stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x->regs[STV6110x_STAT1]); |
197 | if (!STV6110x_GETFIELD(STAT1_CALRC_STRT, stv6110x_regs[STV6110x_STAT1])) | 209 | if (!STV6110x_GETFIELD(STAT1_CALRC_STRT, stv6110x->regs[STV6110x_STAT1])) |
198 | break; | 210 | break; |
199 | msleep(1); | 211 | msleep(1); |
200 | } | 212 | } |
201 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x1); /* cal. done */ | 213 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x1); /* cal. done */ |
202 | stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x_regs[STV6110x_CTRL3]); | 214 | stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x->regs[STV6110x_CTRL3]); |
203 | 215 | ||
204 | return 0; | 216 | return 0; |
205 | } | 217 | } |
@@ -208,8 +220,8 @@ static int stv6110x_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) | |||
208 | { | 220 | { |
209 | struct stv6110x_state *stv6110x = fe->tuner_priv; | 221 | struct stv6110x_state *stv6110x = fe->tuner_priv; |
210 | 222 | ||
211 | stv6110x_read_reg(stv6110x, STV6110x_CTRL3, &stv6110x_regs[STV6110x_CTRL3]); | 223 | stv6110x_read_reg(stv6110x, STV6110x_CTRL3, &stv6110x->regs[STV6110x_CTRL3]); |
212 | *bandwidth = (STV6110x_GETFIELD(CTRL3_CF, stv6110x_regs[STV6110x_CTRL3]) + 5) * 2000000; | 224 | *bandwidth = (STV6110x_GETFIELD(CTRL3_CF, stv6110x->regs[STV6110x_CTRL3]) + 5) * 2000000; |
213 | 225 | ||
214 | return 0; | 226 | return 0; |
215 | } | 227 | } |
@@ -222,20 +234,20 @@ static int stv6110x_set_refclock(struct dvb_frontend *fe, u32 refclock) | |||
222 | switch (refclock) { | 234 | switch (refclock) { |
223 | default: | 235 | default: |
224 | case 1: | 236 | case 1: |
225 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_CO_DIV, 0); | 237 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 0); |
226 | break; | 238 | break; |
227 | case 2: | 239 | case 2: |
228 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_CO_DIV, 1); | 240 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 1); |
229 | break; | 241 | break; |
230 | case 4: | 242 | case 4: |
231 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_CO_DIV, 2); | 243 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 2); |
232 | break; | 244 | break; |
233 | case 8: | 245 | case 8: |
234 | case 0: | 246 | case 0: |
235 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_CO_DIV, 3); | 247 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 3); |
236 | break; | 248 | break; |
237 | } | 249 | } |
238 | stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x_regs[STV6110x_CTRL2]); | 250 | stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x->regs[STV6110x_CTRL2]); |
239 | 251 | ||
240 | return 0; | 252 | return 0; |
241 | } | 253 | } |
@@ -244,8 +256,8 @@ static int stv6110x_get_bbgain(struct dvb_frontend *fe, u32 *gain) | |||
244 | { | 256 | { |
245 | struct stv6110x_state *stv6110x = fe->tuner_priv; | 257 | struct stv6110x_state *stv6110x = fe->tuner_priv; |
246 | 258 | ||
247 | stv6110x_read_reg(stv6110x, STV6110x_CTRL2, &stv6110x_regs[STV6110x_CTRL2]); | 259 | stv6110x_read_reg(stv6110x, STV6110x_CTRL2, &stv6110x->regs[STV6110x_CTRL2]); |
248 | *gain = 2 * STV6110x_GETFIELD(CTRL2_BBGAIN, stv6110x_regs[STV6110x_CTRL2]); | 260 | *gain = 2 * STV6110x_GETFIELD(CTRL2_BBGAIN, stv6110x->regs[STV6110x_CTRL2]); |
249 | 261 | ||
250 | return 0; | 262 | return 0; |
251 | } | 263 | } |
@@ -254,8 +266,8 @@ static int stv6110x_set_bbgain(struct dvb_frontend *fe, u32 gain) | |||
254 | { | 266 | { |
255 | struct stv6110x_state *stv6110x = fe->tuner_priv; | 267 | struct stv6110x_state *stv6110x = fe->tuner_priv; |
256 | 268 | ||
257 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_BBGAIN, gain / 2); | 269 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_BBGAIN, gain / 2); |
258 | stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x_regs[STV6110x_CTRL2]); | 270 | stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x->regs[STV6110x_CTRL2]); |
259 | 271 | ||
260 | return 0; | 272 | return 0; |
261 | } | 273 | } |
@@ -267,19 +279,19 @@ static int stv6110x_set_mode(struct dvb_frontend *fe, enum tuner_mode mode) | |||
267 | 279 | ||
268 | switch (mode) { | 280 | switch (mode) { |
269 | case TUNER_SLEEP: | 281 | case TUNER_SLEEP: |
270 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_SYN, 0); | 282 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_SYN, 0); |
271 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_RX, 0); | 283 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_RX, 0); |
272 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_LPT, 0); | 284 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_LPT, 0); |
273 | break; | 285 | break; |
274 | 286 | ||
275 | case TUNER_WAKE: | 287 | case TUNER_WAKE: |
276 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_SYN, 1); | 288 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_SYN, 1); |
277 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_RX, 1); | 289 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_RX, 1); |
278 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_LPT, 1); | 290 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_LPT, 1); |
279 | break; | 291 | break; |
280 | } | 292 | } |
281 | 293 | ||
282 | ret = stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x_regs[STV6110x_CTRL1]); | 294 | ret = stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x->regs[STV6110x_CTRL1]); |
283 | if (ret < 0) { | 295 | if (ret < 0) { |
284 | dprintk(FE_ERROR, 1, "I/O Error"); | 296 | dprintk(FE_ERROR, 1, "I/O Error"); |
285 | return -EIO; | 297 | return -EIO; |
@@ -297,9 +309,9 @@ static int stv6110x_get_status(struct dvb_frontend *fe, u32 *status) | |||
297 | { | 309 | { |
298 | struct stv6110x_state *stv6110x = fe->tuner_priv; | 310 | struct stv6110x_state *stv6110x = fe->tuner_priv; |
299 | 311 | ||
300 | stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x_regs[STV6110x_STAT1]); | 312 | stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x->regs[STV6110x_STAT1]); |
301 | 313 | ||
302 | if (STV6110x_GETFIELD(STAT1_LOCK, stv6110x_regs[STV6110x_STAT1])) | 314 | if (STV6110x_GETFIELD(STAT1_LOCK, stv6110x->regs[STV6110x_STAT1])) |
303 | *status = TUNER_PHASELOCKED; | 315 | *status = TUNER_PHASELOCKED; |
304 | else | 316 | else |
305 | *status = 0; | 317 | *status = 0; |
@@ -349,6 +361,8 @@ struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe, | |||
349 | struct i2c_adapter *i2c) | 361 | struct i2c_adapter *i2c) |
350 | { | 362 | { |
351 | struct stv6110x_state *stv6110x; | 363 | struct stv6110x_state *stv6110x; |
364 | u8 default_regs[] = {0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e}; | ||
365 | int ret; | ||
352 | 366 | ||
353 | stv6110x = kzalloc(sizeof (struct stv6110x_state), GFP_KERNEL); | 367 | stv6110x = kzalloc(sizeof (struct stv6110x_state), GFP_KERNEL); |
354 | if (stv6110x == NULL) | 368 | if (stv6110x == NULL) |
@@ -357,6 +371,44 @@ struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe, | |||
357 | stv6110x->i2c = i2c; | 371 | stv6110x->i2c = i2c; |
358 | stv6110x->config = config; | 372 | stv6110x->config = config; |
359 | stv6110x->devctl = &stv6110x_ctl; | 373 | stv6110x->devctl = &stv6110x_ctl; |
374 | memcpy(stv6110x->regs, default_regs, 8); | ||
375 | |||
376 | /* setup divider */ | ||
377 | switch (stv6110x->config->clk_div) { | ||
378 | default: | ||
379 | case 1: | ||
380 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 0); | ||
381 | break; | ||
382 | case 2: | ||
383 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 1); | ||
384 | break; | ||
385 | case 4: | ||
386 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 2); | ||
387 | break; | ||
388 | case 8: | ||
389 | case 0: | ||
390 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 3); | ||
391 | break; | ||
392 | } | ||
393 | |||
394 | if (fe->ops.i2c_gate_ctrl) { | ||
395 | ret = fe->ops.i2c_gate_ctrl(fe, 1); | ||
396 | if (ret < 0) | ||
397 | goto error; | ||
398 | } | ||
399 | |||
400 | ret = stv6110x_write_regs(stv6110x, 0, stv6110x->regs, | ||
401 | ARRAY_SIZE(stv6110x->regs)); | ||
402 | if (ret < 0) { | ||
403 | dprintk(FE_ERROR, 1, "Initialization failed"); | ||
404 | goto error; | ||
405 | } | ||
406 | |||
407 | if (fe->ops.i2c_gate_ctrl) { | ||
408 | ret = fe->ops.i2c_gate_ctrl(fe, 0); | ||
409 | if (ret < 0) | ||
410 | goto error; | ||
411 | } | ||
360 | 412 | ||
361 | fe->tuner_priv = stv6110x; | 413 | fe->tuner_priv = stv6110x; |
362 | fe->ops.tuner_ops = stv6110x_ops; | 414 | fe->ops.tuner_ops = stv6110x_ops; |
diff --git a/drivers/media/dvb/frontends/stv6110x.h b/drivers/media/dvb/frontends/stv6110x.h index a38257080e01..2429ae6d7847 100644 --- a/drivers/media/dvb/frontends/stv6110x.h +++ b/drivers/media/dvb/frontends/stv6110x.h | |||
@@ -26,6 +26,7 @@ | |||
26 | struct stv6110x_config { | 26 | struct stv6110x_config { |
27 | u8 addr; | 27 | u8 addr; |
28 | u32 refclk; | 28 | u32 refclk; |
29 | u8 clk_div; /* divisor value for the output clock */ | ||
29 | }; | 30 | }; |
30 | 31 | ||
31 | enum tuner_mode { | 32 | enum tuner_mode { |
diff --git a/drivers/media/dvb/frontends/stv6110x_priv.h b/drivers/media/dvb/frontends/stv6110x_priv.h index 7260da633d49..0ec936a660a7 100644 --- a/drivers/media/dvb/frontends/stv6110x_priv.h +++ b/drivers/media/dvb/frontends/stv6110x_priv.h | |||
@@ -68,6 +68,7 @@ | |||
68 | struct stv6110x_state { | 68 | struct stv6110x_state { |
69 | struct i2c_adapter *i2c; | 69 | struct i2c_adapter *i2c; |
70 | const struct stv6110x_config *config; | 70 | const struct stv6110x_config *config; |
71 | u8 regs[8]; | ||
71 | 72 | ||
72 | struct stv6110x_devctl *devctl; | 73 | struct stv6110x_devctl *devctl; |
73 | }; | 74 | }; |
diff --git a/drivers/media/dvb/frontends/tda665x.c b/drivers/media/dvb/frontends/tda665x.c index 87d52739c828..c44fefe92d97 100644 --- a/drivers/media/dvb/frontends/tda665x.c +++ b/drivers/media/dvb/frontends/tda665x.c | |||
@@ -133,7 +133,7 @@ static int tda665x_set_state(struct dvb_frontend *fe, | |||
133 | frequency += config->ref_divider >> 1; | 133 | frequency += config->ref_divider >> 1; |
134 | frequency /= config->ref_divider; | 134 | frequency /= config->ref_divider; |
135 | 135 | ||
136 | buf[0] = (u8) (frequency & 0x7f00) >> 8; | 136 | buf[0] = (u8) ((frequency & 0x7f00) >> 8); |
137 | buf[1] = (u8) (frequency & 0x00ff) >> 0; | 137 | buf[1] = (u8) (frequency & 0x00ff) >> 0; |
138 | buf[2] = 0x80 | 0x40 | 0x02; | 138 | buf[2] = 0x80 | 0x40 | 0x02; |
139 | buf[3] = 0x00; | 139 | buf[3] = 0x00; |
diff --git a/drivers/media/dvb/frontends/tda8261.c b/drivers/media/dvb/frontends/tda8261.c index 320c3c36d8b2..614afcec05f1 100644 --- a/drivers/media/dvb/frontends/tda8261.c +++ b/drivers/media/dvb/frontends/tda8261.c | |||
@@ -39,7 +39,7 @@ static int tda8261_read(struct tda8261_state *state, u8 *buf) | |||
39 | { | 39 | { |
40 | const struct tda8261_config *config = state->config; | 40 | const struct tda8261_config *config = state->config; |
41 | int err = 0; | 41 | int err = 0; |
42 | struct i2c_msg msg = { .addr = config->addr, .flags = I2C_M_RD,.buf = buf, .len = 2 }; | 42 | struct i2c_msg msg = { .addr = config->addr, .flags = I2C_M_RD,.buf = buf, .len = 1 }; |
43 | 43 | ||
44 | if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) | 44 | if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) |
45 | printk("%s: read error, err=%d\n", __func__, err); | 45 | printk("%s: read error, err=%d\n", __func__, err); |
diff --git a/drivers/media/dvb/frontends/zl10036.c b/drivers/media/dvb/frontends/zl10036.c index 4e814ff22b23..34c5de491d2b 100644 --- a/drivers/media/dvb/frontends/zl10036.c +++ b/drivers/media/dvb/frontends/zl10036.c | |||
@@ -411,7 +411,7 @@ static int zl10036_init_regs(struct zl10036_state *state) | |||
411 | state->bf = 0xff; | 411 | state->bf = 0xff; |
412 | 412 | ||
413 | if (!state->config->rf_loop_enable) | 413 | if (!state->config->rf_loop_enable) |
414 | zl10036_init_tab[1][2] |= 0x01; | 414 | zl10036_init_tab[1][0] |= 0x01; |
415 | 415 | ||
416 | deb_info("%s\n", __func__); | 416 | deb_info("%s\n", __func__); |
417 | 417 | ||
diff --git a/drivers/media/dvb/frontends/zl10039.c b/drivers/media/dvb/frontends/zl10039.c index 11b29cb883e6..c085e58a94bf 100644 --- a/drivers/media/dvb/frontends/zl10039.c +++ b/drivers/media/dvb/frontends/zl10039.c | |||
@@ -287,7 +287,6 @@ struct dvb_frontend *zl10039_attach(struct dvb_frontend *fe, | |||
287 | break; | 287 | break; |
288 | default: | 288 | default: |
289 | dprintk("Chip ID=%x does not match a known type\n", state->id); | 289 | dprintk("Chip ID=%x does not match a known type\n", state->id); |
290 | break; | ||
291 | goto error; | 290 | goto error; |
292 | } | 291 | } |
293 | 292 | ||
diff --git a/drivers/media/dvb/mantis/mantis_hif.c b/drivers/media/dvb/mantis/mantis_hif.c index 7477dac628b4..5772ebb3a69e 100644 --- a/drivers/media/dvb/mantis/mantis_hif.c +++ b/drivers/media/dvb/mantis/mantis_hif.c | |||
@@ -22,8 +22,6 @@ | |||
22 | #include <linux/signal.h> | 22 | #include <linux/signal.h> |
23 | #include <linux/sched.h> | 23 | #include <linux/sched.h> |
24 | 24 | ||
25 | #include <linux/signal.h> | ||
26 | #include <linux/sched.h> | ||
27 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
28 | 26 | ||
29 | #include "dmxdev.h" | 27 | #include "dmxdev.h" |
diff --git a/drivers/media/dvb/mantis/mantis_input.c b/drivers/media/dvb/mantis/mantis_input.c index 6a9df779441f..4675a3b53c7d 100644 --- a/drivers/media/dvb/mantis/mantis_input.c +++ b/drivers/media/dvb/mantis/mantis_input.c | |||
@@ -126,7 +126,7 @@ int mantis_input_init(struct mantis_pci *mantis) | |||
126 | rc->id.version = 1; | 126 | rc->id.version = 1; |
127 | rc->dev = mantis->pdev->dev; | 127 | rc->dev = mantis->pdev->dev; |
128 | 128 | ||
129 | err = ir_input_register(rc, &ir_mantis); | 129 | err = ir_input_register(rc, &ir_mantis, NULL); |
130 | if (err) { | 130 | if (err) { |
131 | dprintk(MANTIS_ERROR, 1, "IR device registration failed, ret = %d", err); | 131 | dprintk(MANTIS_ERROR, 1, "IR device registration failed, ret = %d", err); |
132 | input_free_device(rc); | 132 | input_free_device(rc); |
diff --git a/drivers/media/dvb/mantis/mantis_pci.c b/drivers/media/dvb/mantis/mantis_pci.c index 6c7534af6b44..59feeb84aec7 100644 --- a/drivers/media/dvb/mantis/mantis_pci.c +++ b/drivers/media/dvb/mantis/mantis_pci.c | |||
@@ -41,11 +41,6 @@ | |||
41 | #include "dvb_frontend.h" | 41 | #include "dvb_frontend.h" |
42 | #include "dvb_net.h" | 42 | #include "dvb_net.h" |
43 | 43 | ||
44 | #include <asm/irq.h> | ||
45 | #include <linux/signal.h> | ||
46 | #include <linux/sched.h> | ||
47 | #include <linux/interrupt.h> | ||
48 | |||
49 | #include "mantis_common.h" | 44 | #include "mantis_common.h" |
50 | #include "mantis_reg.h" | 45 | #include "mantis_reg.h" |
51 | #include "mantis_pci.h" | 46 | #include "mantis_pci.h" |
diff --git a/drivers/media/dvb/ngene/Kconfig b/drivers/media/dvb/ngene/Kconfig new file mode 100644 index 000000000000..3ec8e6fcbb1d --- /dev/null +++ b/drivers/media/dvb/ngene/Kconfig | |||
@@ -0,0 +1,9 @@ | |||
1 | config DVB_NGENE | ||
2 | tristate "Micronas nGene support" | ||
3 | depends on DVB_CORE && PCI && I2C | ||
4 | select DVB_LNBP21 if !DVB_FE_CUSTOMISE | ||
5 | select DVB_STV6110x if !DVB_FE_CUSTOMISE | ||
6 | select DVB_STV090x if !DVB_FE_CUSTOMISE | ||
7 | ---help--- | ||
8 | Support for Micronas PCI express cards with nGene bridge. | ||
9 | |||
diff --git a/drivers/media/dvb/ngene/Makefile b/drivers/media/dvb/ngene/Makefile new file mode 100644 index 000000000000..40435cad4819 --- /dev/null +++ b/drivers/media/dvb/ngene/Makefile | |||
@@ -0,0 +1,11 @@ | |||
1 | # | ||
2 | # Makefile for the nGene device driver | ||
3 | # | ||
4 | |||
5 | ngene-objs := ngene-core.o | ||
6 | |||
7 | obj-$(CONFIG_DVB_NGENE) += ngene.o | ||
8 | |||
9 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ | ||
10 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends/ | ||
11 | |||
diff --git a/drivers/media/dvb/ngene/ngene-core.c b/drivers/media/dvb/ngene/ngene-core.c new file mode 100644 index 000000000000..0150dfe7cfbb --- /dev/null +++ b/drivers/media/dvb/ngene/ngene-core.c | |||
@@ -0,0 +1,2024 @@ | |||
1 | /* | ||
2 | * ngene.c: nGene PCIe bridge driver | ||
3 | * | ||
4 | * Copyright (C) 2005-2007 Micronas | ||
5 | * | ||
6 | * Copyright (C) 2008-2009 Ralph Metzler <rjkm@metzlerbros.de> | ||
7 | * Modifications for new nGene firmware, | ||
8 | * support for EEPROM-copying, | ||
9 | * support for new dual DVB-S2 card prototype | ||
10 | * | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * version 2 only, as published by the Free Software Foundation. | ||
15 | * | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, write to the Free Software | ||
25 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
26 | * 02110-1301, USA | ||
27 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||
28 | */ | ||
29 | |||
30 | #include <linux/module.h> | ||
31 | #include <linux/init.h> | ||
32 | #include <linux/delay.h> | ||
33 | #include <linux/slab.h> | ||
34 | #include <linux/poll.h> | ||
35 | #include <linux/io.h> | ||
36 | #include <asm/div64.h> | ||
37 | #include <linux/pci.h> | ||
38 | #include <linux/pci_ids.h> | ||
39 | #include <linux/smp_lock.h> | ||
40 | #include <linux/timer.h> | ||
41 | #include <linux/version.h> | ||
42 | #include <linux/byteorder/generic.h> | ||
43 | #include <linux/firmware.h> | ||
44 | #include <linux/vmalloc.h> | ||
45 | |||
46 | #include "ngene.h" | ||
47 | |||
48 | #include "stv6110x.h" | ||
49 | #include "stv090x.h" | ||
50 | #include "lnbh24.h" | ||
51 | |||
52 | static int one_adapter = 1; | ||
53 | module_param(one_adapter, int, 0444); | ||
54 | MODULE_PARM_DESC(one_adapter, "Use only one adapter."); | ||
55 | |||
56 | |||
57 | static int debug; | ||
58 | module_param(debug, int, 0444); | ||
59 | MODULE_PARM_DESC(debug, "Print debugging information."); | ||
60 | |||
61 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
62 | |||
63 | #define COMMAND_TIMEOUT_WORKAROUND | ||
64 | |||
65 | #define dprintk if (debug) printk | ||
66 | |||
67 | #define DEVICE_NAME "ngene" | ||
68 | |||
69 | #define ngwriteb(dat, adr) writeb((dat), (char *)(dev->iomem + (adr))) | ||
70 | #define ngwritel(dat, adr) writel((dat), (char *)(dev->iomem + (adr))) | ||
71 | #define ngwriteb(dat, adr) writeb((dat), (char *)(dev->iomem + (adr))) | ||
72 | #define ngreadl(adr) readl(dev->iomem + (adr)) | ||
73 | #define ngreadb(adr) readb(dev->iomem + (adr)) | ||
74 | #define ngcpyto(adr, src, count) memcpy_toio((char *) \ | ||
75 | (dev->iomem + (adr)), (src), (count)) | ||
76 | #define ngcpyfrom(dst, adr, count) memcpy_fromio((dst), (char *) \ | ||
77 | (dev->iomem + (adr)), (count)) | ||
78 | |||
79 | /****************************************************************************/ | ||
80 | /* nGene interrupt handler **************************************************/ | ||
81 | /****************************************************************************/ | ||
82 | |||
83 | static void event_tasklet(unsigned long data) | ||
84 | { | ||
85 | struct ngene *dev = (struct ngene *)data; | ||
86 | |||
87 | while (dev->EventQueueReadIndex != dev->EventQueueWriteIndex) { | ||
88 | struct EVENT_BUFFER Event = | ||
89 | dev->EventQueue[dev->EventQueueReadIndex]; | ||
90 | dev->EventQueueReadIndex = | ||
91 | (dev->EventQueueReadIndex + 1) & (EVENT_QUEUE_SIZE - 1); | ||
92 | |||
93 | if ((Event.UARTStatus & 0x01) && (dev->TxEventNotify)) | ||
94 | dev->TxEventNotify(dev, Event.TimeStamp); | ||
95 | if ((Event.UARTStatus & 0x02) && (dev->RxEventNotify)) | ||
96 | dev->RxEventNotify(dev, Event.TimeStamp, | ||
97 | Event.RXCharacter); | ||
98 | } | ||
99 | } | ||
100 | |||
101 | static void demux_tasklet(unsigned long data) | ||
102 | { | ||
103 | struct ngene_channel *chan = (struct ngene_channel *)data; | ||
104 | struct SBufferHeader *Cur = chan->nextBuffer; | ||
105 | |||
106 | spin_lock_irq(&chan->state_lock); | ||
107 | |||
108 | while (Cur->ngeneBuffer.SR.Flags & 0x80) { | ||
109 | if (chan->mode & NGENE_IO_TSOUT) { | ||
110 | u32 Flags = chan->DataFormatFlags; | ||
111 | if (Cur->ngeneBuffer.SR.Flags & 0x20) | ||
112 | Flags |= BEF_OVERFLOW; | ||
113 | if (chan->pBufferExchange) { | ||
114 | if (!chan->pBufferExchange(chan, | ||
115 | Cur->Buffer1, | ||
116 | chan->Capture1Length, | ||
117 | Cur->ngeneBuffer.SR. | ||
118 | Clock, Flags)) { | ||
119 | /* | ||
120 | We didn't get data | ||
121 | Clear in service flag to make sure we | ||
122 | get called on next interrupt again. | ||
123 | leave fill/empty (0x80) flag alone | ||
124 | to avoid hardware running out of | ||
125 | buffers during startup, we hold only | ||
126 | in run state ( the source may be late | ||
127 | delivering data ) | ||
128 | */ | ||
129 | |||
130 | if (chan->HWState == HWSTATE_RUN) { | ||
131 | Cur->ngeneBuffer.SR.Flags &= | ||
132 | ~0x40; | ||
133 | break; | ||
134 | /* Stop proccessing stream */ | ||
135 | } | ||
136 | } else { | ||
137 | /* We got a valid buffer, | ||
138 | so switch to run state */ | ||
139 | chan->HWState = HWSTATE_RUN; | ||
140 | } | ||
141 | } else { | ||
142 | printk(KERN_ERR DEVICE_NAME ": OOPS\n"); | ||
143 | if (chan->HWState == HWSTATE_RUN) { | ||
144 | Cur->ngeneBuffer.SR.Flags &= ~0x40; | ||
145 | break; /* Stop proccessing stream */ | ||
146 | } | ||
147 | } | ||
148 | if (chan->AudioDTOUpdated) { | ||
149 | printk(KERN_INFO DEVICE_NAME | ||
150 | ": Update AudioDTO = %d\n", | ||
151 | chan->AudioDTOValue); | ||
152 | Cur->ngeneBuffer.SR.DTOUpdate = | ||
153 | chan->AudioDTOValue; | ||
154 | chan->AudioDTOUpdated = 0; | ||
155 | } | ||
156 | } else { | ||
157 | if (chan->HWState == HWSTATE_RUN) { | ||
158 | u32 Flags = 0; | ||
159 | if (Cur->ngeneBuffer.SR.Flags & 0x01) | ||
160 | Flags |= BEF_EVEN_FIELD; | ||
161 | if (Cur->ngeneBuffer.SR.Flags & 0x20) | ||
162 | Flags |= BEF_OVERFLOW; | ||
163 | if (chan->pBufferExchange) | ||
164 | chan->pBufferExchange(chan, | ||
165 | Cur->Buffer1, | ||
166 | chan-> | ||
167 | Capture1Length, | ||
168 | Cur->ngeneBuffer. | ||
169 | SR.Clock, Flags); | ||
170 | if (chan->pBufferExchange2) | ||
171 | chan->pBufferExchange2(chan, | ||
172 | Cur->Buffer2, | ||
173 | chan-> | ||
174 | Capture2Length, | ||
175 | Cur->ngeneBuffer. | ||
176 | SR.Clock, Flags); | ||
177 | } else if (chan->HWState != HWSTATE_STOP) | ||
178 | chan->HWState = HWSTATE_RUN; | ||
179 | } | ||
180 | Cur->ngeneBuffer.SR.Flags = 0x00; | ||
181 | Cur = Cur->Next; | ||
182 | } | ||
183 | chan->nextBuffer = Cur; | ||
184 | |||
185 | spin_unlock_irq(&chan->state_lock); | ||
186 | } | ||
187 | |||
188 | static irqreturn_t irq_handler(int irq, void *dev_id) | ||
189 | { | ||
190 | struct ngene *dev = (struct ngene *)dev_id; | ||
191 | u32 icounts = 0; | ||
192 | irqreturn_t rc = IRQ_NONE; | ||
193 | u32 i = MAX_STREAM; | ||
194 | u8 *tmpCmdDoneByte; | ||
195 | |||
196 | if (dev->BootFirmware) { | ||
197 | icounts = ngreadl(NGENE_INT_COUNTS); | ||
198 | if (icounts != dev->icounts) { | ||
199 | ngwritel(0, FORCE_NMI); | ||
200 | dev->cmd_done = 1; | ||
201 | wake_up(&dev->cmd_wq); | ||
202 | dev->icounts = icounts; | ||
203 | rc = IRQ_HANDLED; | ||
204 | } | ||
205 | return rc; | ||
206 | } | ||
207 | |||
208 | ngwritel(0, FORCE_NMI); | ||
209 | |||
210 | spin_lock(&dev->cmd_lock); | ||
211 | tmpCmdDoneByte = dev->CmdDoneByte; | ||
212 | if (tmpCmdDoneByte && | ||
213 | (*tmpCmdDoneByte || | ||
214 | (dev->ngenetohost[0] == 1 && dev->ngenetohost[1] != 0))) { | ||
215 | dev->CmdDoneByte = NULL; | ||
216 | dev->cmd_done = 1; | ||
217 | wake_up(&dev->cmd_wq); | ||
218 | rc = IRQ_HANDLED; | ||
219 | } | ||
220 | spin_unlock(&dev->cmd_lock); | ||
221 | |||
222 | if (dev->EventBuffer->EventStatus & 0x80) { | ||
223 | u8 nextWriteIndex = | ||
224 | (dev->EventQueueWriteIndex + 1) & | ||
225 | (EVENT_QUEUE_SIZE - 1); | ||
226 | if (nextWriteIndex != dev->EventQueueReadIndex) { | ||
227 | dev->EventQueue[dev->EventQueueWriteIndex] = | ||
228 | *(dev->EventBuffer); | ||
229 | dev->EventQueueWriteIndex = nextWriteIndex; | ||
230 | } else { | ||
231 | printk(KERN_ERR DEVICE_NAME ": event overflow\n"); | ||
232 | dev->EventQueueOverflowCount += 1; | ||
233 | dev->EventQueueOverflowFlag = 1; | ||
234 | } | ||
235 | dev->EventBuffer->EventStatus &= ~0x80; | ||
236 | tasklet_schedule(&dev->event_tasklet); | ||
237 | rc = IRQ_HANDLED; | ||
238 | } | ||
239 | |||
240 | while (i > 0) { | ||
241 | i--; | ||
242 | spin_lock(&dev->channel[i].state_lock); | ||
243 | /* if (dev->channel[i].State>=KSSTATE_RUN) { */ | ||
244 | if (dev->channel[i].nextBuffer) { | ||
245 | if ((dev->channel[i].nextBuffer-> | ||
246 | ngeneBuffer.SR.Flags & 0xC0) == 0x80) { | ||
247 | dev->channel[i].nextBuffer-> | ||
248 | ngeneBuffer.SR.Flags |= 0x40; | ||
249 | tasklet_schedule( | ||
250 | &dev->channel[i].demux_tasklet); | ||
251 | rc = IRQ_HANDLED; | ||
252 | } | ||
253 | } | ||
254 | spin_unlock(&dev->channel[i].state_lock); | ||
255 | } | ||
256 | |||
257 | /* Request might have been processed by a previous call. */ | ||
258 | return IRQ_HANDLED; | ||
259 | } | ||
260 | |||
261 | /****************************************************************************/ | ||
262 | /* nGene command interface **************************************************/ | ||
263 | /****************************************************************************/ | ||
264 | |||
265 | static void dump_command_io(struct ngene *dev) | ||
266 | { | ||
267 | u8 buf[8], *b; | ||
268 | |||
269 | ngcpyfrom(buf, HOST_TO_NGENE, 8); | ||
270 | printk(KERN_ERR "host_to_ngene (%04x): %02x %02x %02x %02x %02x %02x %02x %02x\n", | ||
271 | HOST_TO_NGENE, buf[0], buf[1], buf[2], buf[3], | ||
272 | buf[4], buf[5], buf[6], buf[7]); | ||
273 | |||
274 | ngcpyfrom(buf, NGENE_TO_HOST, 8); | ||
275 | printk(KERN_ERR "ngene_to_host (%04x): %02x %02x %02x %02x %02x %02x %02x %02x\n", | ||
276 | NGENE_TO_HOST, buf[0], buf[1], buf[2], buf[3], | ||
277 | buf[4], buf[5], buf[6], buf[7]); | ||
278 | |||
279 | b = dev->hosttongene; | ||
280 | printk(KERN_ERR "dev->hosttongene (%p): %02x %02x %02x %02x %02x %02x %02x %02x\n", | ||
281 | b, b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]); | ||
282 | |||
283 | b = dev->ngenetohost; | ||
284 | printk(KERN_ERR "dev->ngenetohost (%p): %02x %02x %02x %02x %02x %02x %02x %02x\n", | ||
285 | b, b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]); | ||
286 | } | ||
287 | |||
288 | static int ngene_command_mutex(struct ngene *dev, struct ngene_command *com) | ||
289 | { | ||
290 | int ret; | ||
291 | u8 *tmpCmdDoneByte; | ||
292 | |||
293 | dev->cmd_done = 0; | ||
294 | |||
295 | if (com->cmd.hdr.Opcode == CMD_FWLOAD_PREPARE) { | ||
296 | dev->BootFirmware = 1; | ||
297 | dev->icounts = ngreadl(NGENE_INT_COUNTS); | ||
298 | ngwritel(0, NGENE_COMMAND); | ||
299 | ngwritel(0, NGENE_COMMAND_HI); | ||
300 | ngwritel(0, NGENE_STATUS); | ||
301 | ngwritel(0, NGENE_STATUS_HI); | ||
302 | ngwritel(0, NGENE_EVENT); | ||
303 | ngwritel(0, NGENE_EVENT_HI); | ||
304 | } else if (com->cmd.hdr.Opcode == CMD_FWLOAD_FINISH) { | ||
305 | u64 fwio = dev->PAFWInterfaceBuffer; | ||
306 | |||
307 | ngwritel(fwio & 0xffffffff, NGENE_COMMAND); | ||
308 | ngwritel(fwio >> 32, NGENE_COMMAND_HI); | ||
309 | ngwritel((fwio + 256) & 0xffffffff, NGENE_STATUS); | ||
310 | ngwritel((fwio + 256) >> 32, NGENE_STATUS_HI); | ||
311 | ngwritel((fwio + 512) & 0xffffffff, NGENE_EVENT); | ||
312 | ngwritel((fwio + 512) >> 32, NGENE_EVENT_HI); | ||
313 | } | ||
314 | |||
315 | memcpy(dev->FWInterfaceBuffer, com->cmd.raw8, com->in_len + 2); | ||
316 | |||
317 | if (dev->BootFirmware) | ||
318 | ngcpyto(HOST_TO_NGENE, com->cmd.raw8, com->in_len + 2); | ||
319 | |||
320 | spin_lock_irq(&dev->cmd_lock); | ||
321 | tmpCmdDoneByte = dev->ngenetohost + com->out_len; | ||
322 | if (!com->out_len) | ||
323 | tmpCmdDoneByte++; | ||
324 | *tmpCmdDoneByte = 0; | ||
325 | dev->ngenetohost[0] = 0; | ||
326 | dev->ngenetohost[1] = 0; | ||
327 | dev->CmdDoneByte = tmpCmdDoneByte; | ||
328 | spin_unlock_irq(&dev->cmd_lock); | ||
329 | |||
330 | /* Notify 8051. */ | ||
331 | ngwritel(1, FORCE_INT); | ||
332 | |||
333 | ret = wait_event_timeout(dev->cmd_wq, dev->cmd_done == 1, 2 * HZ); | ||
334 | if (!ret) { | ||
335 | /*ngwritel(0, FORCE_NMI);*/ | ||
336 | |||
337 | printk(KERN_ERR DEVICE_NAME | ||
338 | ": Command timeout cmd=%02x prev=%02x\n", | ||
339 | com->cmd.hdr.Opcode, dev->prev_cmd); | ||
340 | dump_command_io(dev); | ||
341 | return -1; | ||
342 | } | ||
343 | if (com->cmd.hdr.Opcode == CMD_FWLOAD_FINISH) | ||
344 | dev->BootFirmware = 0; | ||
345 | |||
346 | dev->prev_cmd = com->cmd.hdr.Opcode; | ||
347 | |||
348 | if (!com->out_len) | ||
349 | return 0; | ||
350 | |||
351 | memcpy(com->cmd.raw8, dev->ngenetohost, com->out_len); | ||
352 | |||
353 | return 0; | ||
354 | } | ||
355 | |||
356 | static int ngene_command(struct ngene *dev, struct ngene_command *com) | ||
357 | { | ||
358 | int result; | ||
359 | |||
360 | down(&dev->cmd_mutex); | ||
361 | result = ngene_command_mutex(dev, com); | ||
362 | up(&dev->cmd_mutex); | ||
363 | return result; | ||
364 | } | ||
365 | |||
366 | |||
367 | static int ngene_command_i2c_read(struct ngene *dev, u8 adr, | ||
368 | u8 *out, u8 outlen, u8 *in, u8 inlen, int flag) | ||
369 | { | ||
370 | struct ngene_command com; | ||
371 | |||
372 | com.cmd.hdr.Opcode = CMD_I2C_READ; | ||
373 | com.cmd.hdr.Length = outlen + 3; | ||
374 | com.cmd.I2CRead.Device = adr << 1; | ||
375 | memcpy(com.cmd.I2CRead.Data, out, outlen); | ||
376 | com.cmd.I2CRead.Data[outlen] = inlen; | ||
377 | com.cmd.I2CRead.Data[outlen + 1] = 0; | ||
378 | com.in_len = outlen + 3; | ||
379 | com.out_len = inlen + 1; | ||
380 | |||
381 | if (ngene_command(dev, &com) < 0) | ||
382 | return -EIO; | ||
383 | |||
384 | if ((com.cmd.raw8[0] >> 1) != adr) | ||
385 | return -EIO; | ||
386 | |||
387 | if (flag) | ||
388 | memcpy(in, com.cmd.raw8, inlen + 1); | ||
389 | else | ||
390 | memcpy(in, com.cmd.raw8 + 1, inlen); | ||
391 | return 0; | ||
392 | } | ||
393 | |||
394 | static int ngene_command_i2c_write(struct ngene *dev, u8 adr, | ||
395 | u8 *out, u8 outlen) | ||
396 | { | ||
397 | struct ngene_command com; | ||
398 | |||
399 | |||
400 | com.cmd.hdr.Opcode = CMD_I2C_WRITE; | ||
401 | com.cmd.hdr.Length = outlen + 1; | ||
402 | com.cmd.I2CRead.Device = adr << 1; | ||
403 | memcpy(com.cmd.I2CRead.Data, out, outlen); | ||
404 | com.in_len = outlen + 1; | ||
405 | com.out_len = 1; | ||
406 | |||
407 | if (ngene_command(dev, &com) < 0) | ||
408 | return -EIO; | ||
409 | |||
410 | if (com.cmd.raw8[0] == 1) | ||
411 | return -EIO; | ||
412 | |||
413 | return 0; | ||
414 | } | ||
415 | |||
416 | static int ngene_command_load_firmware(struct ngene *dev, | ||
417 | u8 *ngene_fw, u32 size) | ||
418 | { | ||
419 | #define FIRSTCHUNK (1024) | ||
420 | u32 cleft; | ||
421 | struct ngene_command com; | ||
422 | |||
423 | com.cmd.hdr.Opcode = CMD_FWLOAD_PREPARE; | ||
424 | com.cmd.hdr.Length = 0; | ||
425 | com.in_len = 0; | ||
426 | com.out_len = 0; | ||
427 | |||
428 | ngene_command(dev, &com); | ||
429 | |||
430 | cleft = (size + 3) & ~3; | ||
431 | if (cleft > FIRSTCHUNK) { | ||
432 | ngcpyto(PROGRAM_SRAM + FIRSTCHUNK, ngene_fw + FIRSTCHUNK, | ||
433 | cleft - FIRSTCHUNK); | ||
434 | cleft = FIRSTCHUNK; | ||
435 | } | ||
436 | ngcpyto(DATA_FIFO_AREA, ngene_fw, cleft); | ||
437 | |||
438 | memset(&com, 0, sizeof(struct ngene_command)); | ||
439 | com.cmd.hdr.Opcode = CMD_FWLOAD_FINISH; | ||
440 | com.cmd.hdr.Length = 4; | ||
441 | com.cmd.FWLoadFinish.Address = DATA_FIFO_AREA; | ||
442 | com.cmd.FWLoadFinish.Length = (unsigned short)cleft; | ||
443 | com.in_len = 4; | ||
444 | com.out_len = 0; | ||
445 | |||
446 | return ngene_command(dev, &com); | ||
447 | } | ||
448 | |||
449 | |||
450 | static int ngene_command_config_buf(struct ngene *dev, u8 config) | ||
451 | { | ||
452 | struct ngene_command com; | ||
453 | |||
454 | com.cmd.hdr.Opcode = CMD_CONFIGURE_BUFFER; | ||
455 | com.cmd.hdr.Length = 1; | ||
456 | com.cmd.ConfigureBuffers.config = config; | ||
457 | com.in_len = 1; | ||
458 | com.out_len = 0; | ||
459 | |||
460 | if (ngene_command(dev, &com) < 0) | ||
461 | return -EIO; | ||
462 | return 0; | ||
463 | } | ||
464 | |||
465 | static int ngene_command_config_free_buf(struct ngene *dev, u8 *config) | ||
466 | { | ||
467 | struct ngene_command com; | ||
468 | |||
469 | com.cmd.hdr.Opcode = CMD_CONFIGURE_FREE_BUFFER; | ||
470 | com.cmd.hdr.Length = 6; | ||
471 | memcpy(&com.cmd.ConfigureBuffers.config, config, 6); | ||
472 | com.in_len = 6; | ||
473 | com.out_len = 0; | ||
474 | |||
475 | if (ngene_command(dev, &com) < 0) | ||
476 | return -EIO; | ||
477 | |||
478 | return 0; | ||
479 | } | ||
480 | |||
481 | static int ngene_command_gpio_set(struct ngene *dev, u8 select, u8 level) | ||
482 | { | ||
483 | struct ngene_command com; | ||
484 | |||
485 | com.cmd.hdr.Opcode = CMD_SET_GPIO_PIN; | ||
486 | com.cmd.hdr.Length = 1; | ||
487 | com.cmd.SetGpioPin.select = select | (level << 7); | ||
488 | com.in_len = 1; | ||
489 | com.out_len = 0; | ||
490 | |||
491 | return ngene_command(dev, &com); | ||
492 | } | ||
493 | |||
494 | |||
495 | /* | ||
496 | 02000640 is sample on rising edge. | ||
497 | 02000740 is sample on falling edge. | ||
498 | 02000040 is ignore "valid" signal | ||
499 | |||
500 | 0: FD_CTL1 Bit 7,6 must be 0,1 | ||
501 | 7 disable(fw controlled) | ||
502 | 6 0-AUX,1-TS | ||
503 | 5 0-par,1-ser | ||
504 | 4 0-lsb/1-msb | ||
505 | 3,2 reserved | ||
506 | 1,0 0-no sync, 1-use ext. start, 2-use 0x47, 3-both | ||
507 | 1: FD_CTL2 has 3-valid must be hi, 2-use valid, 1-edge | ||
508 | 2: FD_STA is read-only. 0-sync | ||
509 | 3: FD_INSYNC is number of 47s to trigger "in sync". | ||
510 | 4: FD_OUTSYNC is number of 47s to trigger "out of sync". | ||
511 | 5: FD_MAXBYTE1 is low-order of bytes per packet. | ||
512 | 6: FD_MAXBYTE2 is high-order of bytes per packet. | ||
513 | 7: Top byte is unused. | ||
514 | */ | ||
515 | |||
516 | /****************************************************************************/ | ||
517 | |||
518 | static u8 TSFeatureDecoderSetup[8 * 4] = { | ||
519 | 0x42, 0x00, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00, | ||
520 | 0x40, 0x06, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00, /* DRXH */ | ||
521 | 0x71, 0x07, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00, /* DRXHser */ | ||
522 | 0x72, 0x06, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00, /* S2ser */ | ||
523 | }; | ||
524 | |||
525 | /* Set NGENE I2S Config to 16 bit packed */ | ||
526 | static u8 I2SConfiguration[] = { | ||
527 | 0x00, 0x10, 0x00, 0x00, | ||
528 | 0x80, 0x10, 0x00, 0x00, | ||
529 | }; | ||
530 | |||
531 | static u8 SPDIFConfiguration[10] = { | ||
532 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | ||
533 | }; | ||
534 | |||
535 | /* Set NGENE I2S Config to transport stream compatible mode */ | ||
536 | |||
537 | static u8 TS_I2SConfiguration[4] = { 0x3E, 0x1A, 0x00, 0x00 }; /*3e 18 00 00 ?*/ | ||
538 | |||
539 | static u8 TS_I2SOutConfiguration[4] = { 0x80, 0x20, 0x00, 0x00 }; | ||
540 | |||
541 | static u8 ITUDecoderSetup[4][16] = { | ||
542 | {0x1c, 0x13, 0x01, 0x68, 0x3d, 0x90, 0x14, 0x20, /* SDTV */ | ||
543 | 0x00, 0x00, 0x01, 0xb0, 0x9c, 0x00, 0x00, 0x00}, | ||
544 | {0x9c, 0x03, 0x23, 0xC0, 0x60, 0x0E, 0x13, 0x00, | ||
545 | 0x00, 0x00, 0x00, 0x01, 0xB0, 0x00, 0x00, 0x00}, | ||
546 | {0x9f, 0x00, 0x23, 0xC0, 0x60, 0x0F, 0x13, 0x00, /* HDTV 1080i50 */ | ||
547 | 0x00, 0x00, 0x00, 0x01, 0xB0, 0x00, 0x00, 0x00}, | ||
548 | {0x9c, 0x01, 0x23, 0xC0, 0x60, 0x0E, 0x13, 0x00, /* HDTV 1080i60 */ | ||
549 | 0x00, 0x00, 0x00, 0x01, 0xB0, 0x00, 0x00, 0x00}, | ||
550 | }; | ||
551 | |||
552 | /* | ||
553 | * 50 48 60 gleich | ||
554 | * 27p50 9f 00 22 80 42 69 18 ... | ||
555 | * 27p60 93 00 22 80 82 69 1c ... | ||
556 | */ | ||
557 | |||
558 | /* Maxbyte to 1144 (for raw data) */ | ||
559 | static u8 ITUFeatureDecoderSetup[8] = { | ||
560 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x04, 0x00 | ||
561 | }; | ||
562 | |||
563 | static void FillTSBuffer(void *Buffer, int Length, u32 Flags) | ||
564 | { | ||
565 | u32 *ptr = Buffer; | ||
566 | |||
567 | memset(Buffer, 0xff, Length); | ||
568 | while (Length > 0) { | ||
569 | if (Flags & DF_SWAP32) | ||
570 | *ptr = 0x471FFF10; | ||
571 | else | ||
572 | *ptr = 0x10FF1F47; | ||
573 | ptr += (188 / 4); | ||
574 | Length -= 188; | ||
575 | } | ||
576 | } | ||
577 | |||
578 | |||
579 | static void flush_buffers(struct ngene_channel *chan) | ||
580 | { | ||
581 | u8 val; | ||
582 | |||
583 | do { | ||
584 | msleep(1); | ||
585 | spin_lock_irq(&chan->state_lock); | ||
586 | val = chan->nextBuffer->ngeneBuffer.SR.Flags & 0x80; | ||
587 | spin_unlock_irq(&chan->state_lock); | ||
588 | } while (val); | ||
589 | } | ||
590 | |||
591 | static void clear_buffers(struct ngene_channel *chan) | ||
592 | { | ||
593 | struct SBufferHeader *Cur = chan->nextBuffer; | ||
594 | |||
595 | do { | ||
596 | memset(&Cur->ngeneBuffer.SR, 0, sizeof(Cur->ngeneBuffer.SR)); | ||
597 | if (chan->mode & NGENE_IO_TSOUT) | ||
598 | FillTSBuffer(Cur->Buffer1, | ||
599 | chan->Capture1Length, | ||
600 | chan->DataFormatFlags); | ||
601 | Cur = Cur->Next; | ||
602 | } while (Cur != chan->nextBuffer); | ||
603 | |||
604 | if (chan->mode & NGENE_IO_TSOUT) { | ||
605 | chan->nextBuffer->ngeneBuffer.SR.DTOUpdate = | ||
606 | chan->AudioDTOValue; | ||
607 | chan->AudioDTOUpdated = 0; | ||
608 | |||
609 | Cur = chan->TSIdleBuffer.Head; | ||
610 | |||
611 | do { | ||
612 | memset(&Cur->ngeneBuffer.SR, 0, | ||
613 | sizeof(Cur->ngeneBuffer.SR)); | ||
614 | FillTSBuffer(Cur->Buffer1, | ||
615 | chan->Capture1Length, | ||
616 | chan->DataFormatFlags); | ||
617 | Cur = Cur->Next; | ||
618 | } while (Cur != chan->TSIdleBuffer.Head); | ||
619 | } | ||
620 | } | ||
621 | |||
622 | static int ngene_command_stream_control(struct ngene *dev, u8 stream, | ||
623 | u8 control, u8 mode, u8 flags) | ||
624 | { | ||
625 | struct ngene_channel *chan = &dev->channel[stream]; | ||
626 | struct ngene_command com; | ||
627 | u16 BsUVI = ((stream & 1) ? 0x9400 : 0x9300); | ||
628 | u16 BsSDI = ((stream & 1) ? 0x9600 : 0x9500); | ||
629 | u16 BsSPI = ((stream & 1) ? 0x9800 : 0x9700); | ||
630 | u16 BsSDO = 0x9B00; | ||
631 | |||
632 | /* down(&dev->stream_mutex); */ | ||
633 | while (down_trylock(&dev->stream_mutex)) { | ||
634 | printk(KERN_INFO DEVICE_NAME ": SC locked\n"); | ||
635 | msleep(1); | ||
636 | } | ||
637 | memset(&com, 0, sizeof(com)); | ||
638 | com.cmd.hdr.Opcode = CMD_CONTROL; | ||
639 | com.cmd.hdr.Length = sizeof(struct FW_STREAM_CONTROL) - 2; | ||
640 | com.cmd.StreamControl.Stream = stream | (control ? 8 : 0); | ||
641 | if (chan->mode & NGENE_IO_TSOUT) | ||
642 | com.cmd.StreamControl.Stream |= 0x07; | ||
643 | com.cmd.StreamControl.Control = control | | ||
644 | (flags & SFLAG_ORDER_LUMA_CHROMA); | ||
645 | com.cmd.StreamControl.Mode = mode; | ||
646 | com.in_len = sizeof(struct FW_STREAM_CONTROL); | ||
647 | com.out_len = 0; | ||
648 | |||
649 | dprintk(KERN_INFO DEVICE_NAME | ||
650 | ": Stream=%02x, Control=%02x, Mode=%02x\n", | ||
651 | com.cmd.StreamControl.Stream, com.cmd.StreamControl.Control, | ||
652 | com.cmd.StreamControl.Mode); | ||
653 | |||
654 | chan->Mode = mode; | ||
655 | |||
656 | if (!(control & 0x80)) { | ||
657 | spin_lock_irq(&chan->state_lock); | ||
658 | if (chan->State == KSSTATE_RUN) { | ||
659 | chan->State = KSSTATE_ACQUIRE; | ||
660 | chan->HWState = HWSTATE_STOP; | ||
661 | spin_unlock_irq(&chan->state_lock); | ||
662 | if (ngene_command(dev, &com) < 0) { | ||
663 | up(&dev->stream_mutex); | ||
664 | return -1; | ||
665 | } | ||
666 | /* clear_buffers(chan); */ | ||
667 | flush_buffers(chan); | ||
668 | up(&dev->stream_mutex); | ||
669 | return 0; | ||
670 | } | ||
671 | spin_unlock_irq(&chan->state_lock); | ||
672 | up(&dev->stream_mutex); | ||
673 | return 0; | ||
674 | } | ||
675 | |||
676 | if (mode & SMODE_AUDIO_CAPTURE) { | ||
677 | com.cmd.StreamControl.CaptureBlockCount = | ||
678 | chan->Capture1Length / AUDIO_BLOCK_SIZE; | ||
679 | com.cmd.StreamControl.Buffer_Address = chan->RingBuffer.PAHead; | ||
680 | } else if (mode & SMODE_TRANSPORT_STREAM) { | ||
681 | com.cmd.StreamControl.CaptureBlockCount = | ||
682 | chan->Capture1Length / TS_BLOCK_SIZE; | ||
683 | com.cmd.StreamControl.MaxLinesPerField = | ||
684 | chan->Capture1Length / TS_BLOCK_SIZE; | ||
685 | com.cmd.StreamControl.Buffer_Address = | ||
686 | chan->TSRingBuffer.PAHead; | ||
687 | if (chan->mode & NGENE_IO_TSOUT) { | ||
688 | com.cmd.StreamControl.BytesPerVBILine = | ||
689 | chan->Capture1Length / TS_BLOCK_SIZE; | ||
690 | com.cmd.StreamControl.Stream |= 0x07; | ||
691 | } | ||
692 | } else { | ||
693 | com.cmd.StreamControl.BytesPerVideoLine = chan->nBytesPerLine; | ||
694 | com.cmd.StreamControl.MaxLinesPerField = chan->nLines; | ||
695 | com.cmd.StreamControl.MinLinesPerField = 100; | ||
696 | com.cmd.StreamControl.Buffer_Address = chan->RingBuffer.PAHead; | ||
697 | |||
698 | if (mode & SMODE_VBI_CAPTURE) { | ||
699 | com.cmd.StreamControl.MaxVBILinesPerField = | ||
700 | chan->nVBILines; | ||
701 | com.cmd.StreamControl.MinVBILinesPerField = 0; | ||
702 | com.cmd.StreamControl.BytesPerVBILine = | ||
703 | chan->nBytesPerVBILine; | ||
704 | } | ||
705 | if (flags & SFLAG_COLORBAR) | ||
706 | com.cmd.StreamControl.Stream |= 0x04; | ||
707 | } | ||
708 | |||
709 | spin_lock_irq(&chan->state_lock); | ||
710 | if (mode & SMODE_AUDIO_CAPTURE) { | ||
711 | chan->nextBuffer = chan->RingBuffer.Head; | ||
712 | if (mode & SMODE_AUDIO_SPDIF) { | ||
713 | com.cmd.StreamControl.SetupDataLen = | ||
714 | sizeof(SPDIFConfiguration); | ||
715 | com.cmd.StreamControl.SetupDataAddr = BsSPI; | ||
716 | memcpy(com.cmd.StreamControl.SetupData, | ||
717 | SPDIFConfiguration, sizeof(SPDIFConfiguration)); | ||
718 | } else { | ||
719 | com.cmd.StreamControl.SetupDataLen = 4; | ||
720 | com.cmd.StreamControl.SetupDataAddr = BsSDI; | ||
721 | memcpy(com.cmd.StreamControl.SetupData, | ||
722 | I2SConfiguration + | ||
723 | 4 * dev->card_info->i2s[stream], 4); | ||
724 | } | ||
725 | } else if (mode & SMODE_TRANSPORT_STREAM) { | ||
726 | chan->nextBuffer = chan->TSRingBuffer.Head; | ||
727 | if (stream >= STREAM_AUDIOIN1) { | ||
728 | if (chan->mode & NGENE_IO_TSOUT) { | ||
729 | com.cmd.StreamControl.SetupDataLen = | ||
730 | sizeof(TS_I2SOutConfiguration); | ||
731 | com.cmd.StreamControl.SetupDataAddr = BsSDO; | ||
732 | memcpy(com.cmd.StreamControl.SetupData, | ||
733 | TS_I2SOutConfiguration, | ||
734 | sizeof(TS_I2SOutConfiguration)); | ||
735 | } else { | ||
736 | com.cmd.StreamControl.SetupDataLen = | ||
737 | sizeof(TS_I2SConfiguration); | ||
738 | com.cmd.StreamControl.SetupDataAddr = BsSDI; | ||
739 | memcpy(com.cmd.StreamControl.SetupData, | ||
740 | TS_I2SConfiguration, | ||
741 | sizeof(TS_I2SConfiguration)); | ||
742 | } | ||
743 | } else { | ||
744 | com.cmd.StreamControl.SetupDataLen = 8; | ||
745 | com.cmd.StreamControl.SetupDataAddr = BsUVI + 0x10; | ||
746 | memcpy(com.cmd.StreamControl.SetupData, | ||
747 | TSFeatureDecoderSetup + | ||
748 | 8 * dev->card_info->tsf[stream], 8); | ||
749 | } | ||
750 | } else { | ||
751 | chan->nextBuffer = chan->RingBuffer.Head; | ||
752 | com.cmd.StreamControl.SetupDataLen = | ||
753 | 16 + sizeof(ITUFeatureDecoderSetup); | ||
754 | com.cmd.StreamControl.SetupDataAddr = BsUVI; | ||
755 | memcpy(com.cmd.StreamControl.SetupData, | ||
756 | ITUDecoderSetup[chan->itumode], 16); | ||
757 | memcpy(com.cmd.StreamControl.SetupData + 16, | ||
758 | ITUFeatureDecoderSetup, sizeof(ITUFeatureDecoderSetup)); | ||
759 | } | ||
760 | clear_buffers(chan); | ||
761 | chan->State = KSSTATE_RUN; | ||
762 | if (mode & SMODE_TRANSPORT_STREAM) | ||
763 | chan->HWState = HWSTATE_RUN; | ||
764 | else | ||
765 | chan->HWState = HWSTATE_STARTUP; | ||
766 | spin_unlock_irq(&chan->state_lock); | ||
767 | |||
768 | if (ngene_command(dev, &com) < 0) { | ||
769 | up(&dev->stream_mutex); | ||
770 | return -1; | ||
771 | } | ||
772 | up(&dev->stream_mutex); | ||
773 | return 0; | ||
774 | } | ||
775 | |||
776 | |||
777 | /****************************************************************************/ | ||
778 | /* I2C **********************************************************************/ | ||
779 | /****************************************************************************/ | ||
780 | |||
781 | static void ngene_i2c_set_bus(struct ngene *dev, int bus) | ||
782 | { | ||
783 | if (!(dev->card_info->i2c_access & 2)) | ||
784 | return; | ||
785 | if (dev->i2c_current_bus == bus) | ||
786 | return; | ||
787 | |||
788 | switch (bus) { | ||
789 | case 0: | ||
790 | ngene_command_gpio_set(dev, 3, 0); | ||
791 | ngene_command_gpio_set(dev, 2, 1); | ||
792 | break; | ||
793 | |||
794 | case 1: | ||
795 | ngene_command_gpio_set(dev, 2, 0); | ||
796 | ngene_command_gpio_set(dev, 3, 1); | ||
797 | break; | ||
798 | } | ||
799 | dev->i2c_current_bus = bus; | ||
800 | } | ||
801 | |||
802 | static int ngene_i2c_master_xfer(struct i2c_adapter *adapter, | ||
803 | struct i2c_msg msg[], int num) | ||
804 | { | ||
805 | struct ngene_channel *chan = | ||
806 | (struct ngene_channel *)i2c_get_adapdata(adapter); | ||
807 | struct ngene *dev = chan->dev; | ||
808 | |||
809 | down(&dev->i2c_switch_mutex); | ||
810 | ngene_i2c_set_bus(dev, chan->number); | ||
811 | |||
812 | if (num == 2 && msg[1].flags & I2C_M_RD && !(msg[0].flags & I2C_M_RD)) | ||
813 | if (!ngene_command_i2c_read(dev, msg[0].addr, | ||
814 | msg[0].buf, msg[0].len, | ||
815 | msg[1].buf, msg[1].len, 0)) | ||
816 | goto done; | ||
817 | |||
818 | if (num == 1 && !(msg[0].flags & I2C_M_RD)) | ||
819 | if (!ngene_command_i2c_write(dev, msg[0].addr, | ||
820 | msg[0].buf, msg[0].len)) | ||
821 | goto done; | ||
822 | if (num == 1 && (msg[0].flags & I2C_M_RD)) | ||
823 | if (!ngene_command_i2c_read(dev, msg[0].addr, 0, 0, | ||
824 | msg[0].buf, msg[0].len, 0)) | ||
825 | goto done; | ||
826 | |||
827 | up(&dev->i2c_switch_mutex); | ||
828 | return -EIO; | ||
829 | |||
830 | done: | ||
831 | up(&dev->i2c_switch_mutex); | ||
832 | return num; | ||
833 | } | ||
834 | |||
835 | |||
836 | static u32 ngene_i2c_functionality(struct i2c_adapter *adap) | ||
837 | { | ||
838 | return I2C_FUNC_SMBUS_EMUL; | ||
839 | } | ||
840 | |||
841 | static struct i2c_algorithm ngene_i2c_algo = { | ||
842 | .master_xfer = ngene_i2c_master_xfer, | ||
843 | .functionality = ngene_i2c_functionality, | ||
844 | }; | ||
845 | |||
846 | static int ngene_i2c_init(struct ngene *dev, int dev_nr) | ||
847 | { | ||
848 | struct i2c_adapter *adap = &(dev->channel[dev_nr].i2c_adapter); | ||
849 | |||
850 | i2c_set_adapdata(adap, &(dev->channel[dev_nr])); | ||
851 | adap->class = I2C_CLASS_TV_DIGITAL | I2C_CLASS_TV_ANALOG; | ||
852 | |||
853 | strcpy(adap->name, "nGene"); | ||
854 | |||
855 | adap->algo = &ngene_i2c_algo; | ||
856 | adap->algo_data = (void *)&(dev->channel[dev_nr]); | ||
857 | adap->dev.parent = &dev->pci_dev->dev; | ||
858 | |||
859 | return i2c_add_adapter(adap); | ||
860 | } | ||
861 | |||
862 | |||
863 | /****************************************************************************/ | ||
864 | /* DVB functions and API interface ******************************************/ | ||
865 | /****************************************************************************/ | ||
866 | |||
867 | static void swap_buffer(u32 *p, u32 len) | ||
868 | { | ||
869 | while (len) { | ||
870 | *p = swab32(*p); | ||
871 | p++; | ||
872 | len -= 4; | ||
873 | } | ||
874 | } | ||
875 | |||
876 | |||
877 | static void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags) | ||
878 | { | ||
879 | struct ngene_channel *chan = priv; | ||
880 | |||
881 | |||
882 | #ifdef COMMAND_TIMEOUT_WORKAROUND | ||
883 | if (chan->users > 0) | ||
884 | #endif | ||
885 | dvb_dmx_swfilter(&chan->demux, buf, len); | ||
886 | return 0; | ||
887 | } | ||
888 | |||
889 | u8 fill_ts[188] = { 0x47, 0x1f, 0xff, 0x10 }; | ||
890 | |||
891 | static void *tsout_exchange(void *priv, void *buf, u32 len, | ||
892 | u32 clock, u32 flags) | ||
893 | { | ||
894 | struct ngene_channel *chan = priv; | ||
895 | struct ngene *dev = chan->dev; | ||
896 | u32 alen; | ||
897 | |||
898 | alen = dvb_ringbuffer_avail(&dev->tsout_rbuf); | ||
899 | alen -= alen % 188; | ||
900 | |||
901 | if (alen < len) | ||
902 | FillTSBuffer(buf + alen, len - alen, flags); | ||
903 | else | ||
904 | alen = len; | ||
905 | dvb_ringbuffer_read(&dev->tsout_rbuf, buf, alen); | ||
906 | if (flags & DF_SWAP32) | ||
907 | swap_buffer((u32 *)buf, alen); | ||
908 | wake_up_interruptible(&dev->tsout_rbuf.queue); | ||
909 | return buf; | ||
910 | } | ||
911 | |||
912 | |||
913 | static void set_transfer(struct ngene_channel *chan, int state) | ||
914 | { | ||
915 | u8 control = 0, mode = 0, flags = 0; | ||
916 | struct ngene *dev = chan->dev; | ||
917 | int ret; | ||
918 | |||
919 | /* | ||
920 | printk(KERN_INFO DEVICE_NAME ": st %d\n", state); | ||
921 | msleep(100); | ||
922 | */ | ||
923 | |||
924 | if (state) { | ||
925 | if (chan->running) { | ||
926 | printk(KERN_INFO DEVICE_NAME ": already running\n"); | ||
927 | return; | ||
928 | } | ||
929 | } else { | ||
930 | if (!chan->running) { | ||
931 | printk(KERN_INFO DEVICE_NAME ": already stopped\n"); | ||
932 | return; | ||
933 | } | ||
934 | } | ||
935 | |||
936 | if (dev->card_info->switch_ctrl) | ||
937 | dev->card_info->switch_ctrl(chan, 1, state ^ 1); | ||
938 | |||
939 | if (state) { | ||
940 | spin_lock_irq(&chan->state_lock); | ||
941 | |||
942 | /* printk(KERN_INFO DEVICE_NAME ": lock=%08x\n", | ||
943 | ngreadl(0x9310)); */ | ||
944 | dvb_ringbuffer_flush(&dev->tsout_rbuf); | ||
945 | control = 0x80; | ||
946 | if (chan->mode & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) { | ||
947 | chan->Capture1Length = 512 * 188; | ||
948 | mode = SMODE_TRANSPORT_STREAM; | ||
949 | } | ||
950 | if (chan->mode & NGENE_IO_TSOUT) { | ||
951 | chan->pBufferExchange = tsout_exchange; | ||
952 | /* 0x66666666 = 50MHz *2^33 /250MHz */ | ||
953 | chan->AudioDTOValue = 0x66666666; | ||
954 | /* set_dto(chan, 38810700+1000); */ | ||
955 | /* set_dto(chan, 19392658); */ | ||
956 | } | ||
957 | if (chan->mode & NGENE_IO_TSIN) | ||
958 | chan->pBufferExchange = tsin_exchange; | ||
959 | /* ngwritel(0, 0x9310); */ | ||
960 | spin_unlock_irq(&chan->state_lock); | ||
961 | } else | ||
962 | ;/* printk(KERN_INFO DEVICE_NAME ": lock=%08x\n", | ||
963 | ngreadl(0x9310)); */ | ||
964 | |||
965 | ret = ngene_command_stream_control(dev, chan->number, | ||
966 | control, mode, flags); | ||
967 | if (!ret) | ||
968 | chan->running = state; | ||
969 | else | ||
970 | printk(KERN_ERR DEVICE_NAME ": set_transfer %d failed\n", | ||
971 | state); | ||
972 | if (!state) { | ||
973 | spin_lock_irq(&chan->state_lock); | ||
974 | chan->pBufferExchange = 0; | ||
975 | dvb_ringbuffer_flush(&dev->tsout_rbuf); | ||
976 | spin_unlock_irq(&chan->state_lock); | ||
977 | } | ||
978 | } | ||
979 | |||
980 | static int ngene_start_feed(struct dvb_demux_feed *dvbdmxfeed) | ||
981 | { | ||
982 | struct dvb_demux *dvbdmx = dvbdmxfeed->demux; | ||
983 | struct ngene_channel *chan = dvbdmx->priv; | ||
984 | |||
985 | if (chan->users == 0) { | ||
986 | #ifdef COMMAND_TIMEOUT_WORKAROUND | ||
987 | if (!chan->running) | ||
988 | #endif | ||
989 | set_transfer(chan, 1); | ||
990 | /* msleep(10); */ | ||
991 | } | ||
992 | |||
993 | return ++chan->users; | ||
994 | } | ||
995 | |||
996 | static int ngene_stop_feed(struct dvb_demux_feed *dvbdmxfeed) | ||
997 | { | ||
998 | struct dvb_demux *dvbdmx = dvbdmxfeed->demux; | ||
999 | struct ngene_channel *chan = dvbdmx->priv; | ||
1000 | |||
1001 | if (--chan->users) | ||
1002 | return chan->users; | ||
1003 | |||
1004 | #ifndef COMMAND_TIMEOUT_WORKAROUND | ||
1005 | set_transfer(chan, 0); | ||
1006 | #endif | ||
1007 | |||
1008 | return 0; | ||
1009 | } | ||
1010 | |||
1011 | |||
1012 | |||
1013 | static int my_dvb_dmx_ts_card_init(struct dvb_demux *dvbdemux, char *id, | ||
1014 | int (*start_feed)(struct dvb_demux_feed *), | ||
1015 | int (*stop_feed)(struct dvb_demux_feed *), | ||
1016 | void *priv) | ||
1017 | { | ||
1018 | dvbdemux->priv = priv; | ||
1019 | |||
1020 | dvbdemux->filternum = 256; | ||
1021 | dvbdemux->feednum = 256; | ||
1022 | dvbdemux->start_feed = start_feed; | ||
1023 | dvbdemux->stop_feed = stop_feed; | ||
1024 | dvbdemux->write_to_decoder = 0; | ||
1025 | dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | | ||
1026 | DMX_SECTION_FILTERING | | ||
1027 | DMX_MEMORY_BASED_FILTERING); | ||
1028 | return dvb_dmx_init(dvbdemux); | ||
1029 | } | ||
1030 | |||
1031 | static int my_dvb_dmxdev_ts_card_init(struct dmxdev *dmxdev, | ||
1032 | struct dvb_demux *dvbdemux, | ||
1033 | struct dmx_frontend *hw_frontend, | ||
1034 | struct dmx_frontend *mem_frontend, | ||
1035 | struct dvb_adapter *dvb_adapter) | ||
1036 | { | ||
1037 | int ret; | ||
1038 | |||
1039 | dmxdev->filternum = 256; | ||
1040 | dmxdev->demux = &dvbdemux->dmx; | ||
1041 | dmxdev->capabilities = 0; | ||
1042 | ret = dvb_dmxdev_init(dmxdev, dvb_adapter); | ||
1043 | if (ret < 0) | ||
1044 | return ret; | ||
1045 | |||
1046 | hw_frontend->source = DMX_FRONTEND_0; | ||
1047 | dvbdemux->dmx.add_frontend(&dvbdemux->dmx, hw_frontend); | ||
1048 | mem_frontend->source = DMX_MEMORY_FE; | ||
1049 | dvbdemux->dmx.add_frontend(&dvbdemux->dmx, mem_frontend); | ||
1050 | return dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, hw_frontend); | ||
1051 | } | ||
1052 | |||
1053 | |||
1054 | /****************************************************************************/ | ||
1055 | /* nGene hardware init and release functions ********************************/ | ||
1056 | /****************************************************************************/ | ||
1057 | |||
1058 | static void free_ringbuffer(struct ngene *dev, struct SRingBufferDescriptor *rb) | ||
1059 | { | ||
1060 | struct SBufferHeader *Cur = rb->Head; | ||
1061 | u32 j; | ||
1062 | |||
1063 | if (!Cur) | ||
1064 | return; | ||
1065 | |||
1066 | for (j = 0; j < rb->NumBuffers; j++, Cur = Cur->Next) { | ||
1067 | if (Cur->Buffer1) | ||
1068 | pci_free_consistent(dev->pci_dev, | ||
1069 | rb->Buffer1Length, | ||
1070 | Cur->Buffer1, | ||
1071 | Cur->scList1->Address); | ||
1072 | |||
1073 | if (Cur->Buffer2) | ||
1074 | pci_free_consistent(dev->pci_dev, | ||
1075 | rb->Buffer2Length, | ||
1076 | Cur->Buffer2, | ||
1077 | Cur->scList2->Address); | ||
1078 | } | ||
1079 | |||
1080 | if (rb->SCListMem) | ||
1081 | pci_free_consistent(dev->pci_dev, rb->SCListMemSize, | ||
1082 | rb->SCListMem, rb->PASCListMem); | ||
1083 | |||
1084 | pci_free_consistent(dev->pci_dev, rb->MemSize, rb->Head, rb->PAHead); | ||
1085 | } | ||
1086 | |||
1087 | static void free_idlebuffer(struct ngene *dev, | ||
1088 | struct SRingBufferDescriptor *rb, | ||
1089 | struct SRingBufferDescriptor *tb) | ||
1090 | { | ||
1091 | int j; | ||
1092 | struct SBufferHeader *Cur = tb->Head; | ||
1093 | |||
1094 | if (!rb->Head) | ||
1095 | return; | ||
1096 | free_ringbuffer(dev, rb); | ||
1097 | for (j = 0; j < tb->NumBuffers; j++, Cur = Cur->Next) { | ||
1098 | Cur->Buffer2 = 0; | ||
1099 | Cur->scList2 = 0; | ||
1100 | Cur->ngeneBuffer.Address_of_first_entry_2 = 0; | ||
1101 | Cur->ngeneBuffer.Number_of_entries_2 = 0; | ||
1102 | } | ||
1103 | } | ||
1104 | |||
1105 | static void free_common_buffers(struct ngene *dev) | ||
1106 | { | ||
1107 | u32 i; | ||
1108 | struct ngene_channel *chan; | ||
1109 | |||
1110 | for (i = STREAM_VIDEOIN1; i < MAX_STREAM; i++) { | ||
1111 | chan = &dev->channel[i]; | ||
1112 | free_idlebuffer(dev, &chan->TSIdleBuffer, &chan->TSRingBuffer); | ||
1113 | free_ringbuffer(dev, &chan->RingBuffer); | ||
1114 | free_ringbuffer(dev, &chan->TSRingBuffer); | ||
1115 | } | ||
1116 | |||
1117 | if (dev->OverflowBuffer) | ||
1118 | pci_free_consistent(dev->pci_dev, | ||
1119 | OVERFLOW_BUFFER_SIZE, | ||
1120 | dev->OverflowBuffer, dev->PAOverflowBuffer); | ||
1121 | |||
1122 | if (dev->FWInterfaceBuffer) | ||
1123 | pci_free_consistent(dev->pci_dev, | ||
1124 | 4096, | ||
1125 | dev->FWInterfaceBuffer, | ||
1126 | dev->PAFWInterfaceBuffer); | ||
1127 | } | ||
1128 | |||
1129 | /****************************************************************************/ | ||
1130 | /* Ring buffer handling *****************************************************/ | ||
1131 | /****************************************************************************/ | ||
1132 | |||
1133 | static int create_ring_buffer(struct pci_dev *pci_dev, | ||
1134 | struct SRingBufferDescriptor *descr, u32 NumBuffers) | ||
1135 | { | ||
1136 | dma_addr_t tmp; | ||
1137 | struct SBufferHeader *Head; | ||
1138 | u32 i; | ||
1139 | u32 MemSize = SIZEOF_SBufferHeader * NumBuffers; | ||
1140 | u64 PARingBufferHead; | ||
1141 | u64 PARingBufferCur; | ||
1142 | u64 PARingBufferNext; | ||
1143 | struct SBufferHeader *Cur, *Next; | ||
1144 | |||
1145 | descr->Head = 0; | ||
1146 | descr->MemSize = 0; | ||
1147 | descr->PAHead = 0; | ||
1148 | descr->NumBuffers = 0; | ||
1149 | |||
1150 | if (MemSize < 4096) | ||
1151 | MemSize = 4096; | ||
1152 | |||
1153 | Head = pci_alloc_consistent(pci_dev, MemSize, &tmp); | ||
1154 | PARingBufferHead = tmp; | ||
1155 | |||
1156 | if (!Head) | ||
1157 | return -ENOMEM; | ||
1158 | |||
1159 | memset(Head, 0, MemSize); | ||
1160 | |||
1161 | PARingBufferCur = PARingBufferHead; | ||
1162 | Cur = Head; | ||
1163 | |||
1164 | for (i = 0; i < NumBuffers - 1; i++) { | ||
1165 | Next = (struct SBufferHeader *) | ||
1166 | (((u8 *) Cur) + SIZEOF_SBufferHeader); | ||
1167 | PARingBufferNext = PARingBufferCur + SIZEOF_SBufferHeader; | ||
1168 | Cur->Next = Next; | ||
1169 | Cur->ngeneBuffer.Next = PARingBufferNext; | ||
1170 | Cur = Next; | ||
1171 | PARingBufferCur = PARingBufferNext; | ||
1172 | } | ||
1173 | /* Last Buffer points back to first one */ | ||
1174 | Cur->Next = Head; | ||
1175 | Cur->ngeneBuffer.Next = PARingBufferHead; | ||
1176 | |||
1177 | descr->Head = Head; | ||
1178 | descr->MemSize = MemSize; | ||
1179 | descr->PAHead = PARingBufferHead; | ||
1180 | descr->NumBuffers = NumBuffers; | ||
1181 | |||
1182 | return 0; | ||
1183 | } | ||
1184 | |||
1185 | static int AllocateRingBuffers(struct pci_dev *pci_dev, | ||
1186 | dma_addr_t of, | ||
1187 | struct SRingBufferDescriptor *pRingBuffer, | ||
1188 | u32 Buffer1Length, u32 Buffer2Length) | ||
1189 | { | ||
1190 | dma_addr_t tmp; | ||
1191 | u32 i, j; | ||
1192 | int status = 0; | ||
1193 | u32 SCListMemSize = pRingBuffer->NumBuffers | ||
1194 | * ((Buffer2Length != 0) ? (NUM_SCATTER_GATHER_ENTRIES * 2) : | ||
1195 | NUM_SCATTER_GATHER_ENTRIES) | ||
1196 | * sizeof(struct HW_SCATTER_GATHER_ELEMENT); | ||
1197 | |||
1198 | u64 PASCListMem; | ||
1199 | struct HW_SCATTER_GATHER_ELEMENT *SCListEntry; | ||
1200 | u64 PASCListEntry; | ||
1201 | struct SBufferHeader *Cur; | ||
1202 | void *SCListMem; | ||
1203 | |||
1204 | if (SCListMemSize < 4096) | ||
1205 | SCListMemSize = 4096; | ||
1206 | |||
1207 | SCListMem = pci_alloc_consistent(pci_dev, SCListMemSize, &tmp); | ||
1208 | |||
1209 | PASCListMem = tmp; | ||
1210 | if (SCListMem == NULL) | ||
1211 | return -ENOMEM; | ||
1212 | |||
1213 | memset(SCListMem, 0, SCListMemSize); | ||
1214 | |||
1215 | pRingBuffer->SCListMem = SCListMem; | ||
1216 | pRingBuffer->PASCListMem = PASCListMem; | ||
1217 | pRingBuffer->SCListMemSize = SCListMemSize; | ||
1218 | pRingBuffer->Buffer1Length = Buffer1Length; | ||
1219 | pRingBuffer->Buffer2Length = Buffer2Length; | ||
1220 | |||
1221 | SCListEntry = SCListMem; | ||
1222 | PASCListEntry = PASCListMem; | ||
1223 | Cur = pRingBuffer->Head; | ||
1224 | |||
1225 | for (i = 0; i < pRingBuffer->NumBuffers; i += 1, Cur = Cur->Next) { | ||
1226 | u64 PABuffer; | ||
1227 | |||
1228 | void *Buffer = pci_alloc_consistent(pci_dev, Buffer1Length, | ||
1229 | &tmp); | ||
1230 | PABuffer = tmp; | ||
1231 | |||
1232 | if (Buffer == NULL) | ||
1233 | return -ENOMEM; | ||
1234 | |||
1235 | Cur->Buffer1 = Buffer; | ||
1236 | |||
1237 | SCListEntry->Address = PABuffer; | ||
1238 | SCListEntry->Length = Buffer1Length; | ||
1239 | |||
1240 | Cur->scList1 = SCListEntry; | ||
1241 | Cur->ngeneBuffer.Address_of_first_entry_1 = PASCListEntry; | ||
1242 | Cur->ngeneBuffer.Number_of_entries_1 = | ||
1243 | NUM_SCATTER_GATHER_ENTRIES; | ||
1244 | |||
1245 | SCListEntry += 1; | ||
1246 | PASCListEntry += sizeof(struct HW_SCATTER_GATHER_ELEMENT); | ||
1247 | |||
1248 | #if NUM_SCATTER_GATHER_ENTRIES > 1 | ||
1249 | for (j = 0; j < NUM_SCATTER_GATHER_ENTRIES - 1; j += 1) { | ||
1250 | SCListEntry->Address = of; | ||
1251 | SCListEntry->Length = OVERFLOW_BUFFER_SIZE; | ||
1252 | SCListEntry += 1; | ||
1253 | PASCListEntry += | ||
1254 | sizeof(struct HW_SCATTER_GATHER_ELEMENT); | ||
1255 | } | ||
1256 | #endif | ||
1257 | |||
1258 | if (!Buffer2Length) | ||
1259 | continue; | ||
1260 | |||
1261 | Buffer = pci_alloc_consistent(pci_dev, Buffer2Length, &tmp); | ||
1262 | PABuffer = tmp; | ||
1263 | |||
1264 | if (Buffer == NULL) | ||
1265 | return -ENOMEM; | ||
1266 | |||
1267 | Cur->Buffer2 = Buffer; | ||
1268 | |||
1269 | SCListEntry->Address = PABuffer; | ||
1270 | SCListEntry->Length = Buffer2Length; | ||
1271 | |||
1272 | Cur->scList2 = SCListEntry; | ||
1273 | Cur->ngeneBuffer.Address_of_first_entry_2 = PASCListEntry; | ||
1274 | Cur->ngeneBuffer.Number_of_entries_2 = | ||
1275 | NUM_SCATTER_GATHER_ENTRIES; | ||
1276 | |||
1277 | SCListEntry += 1; | ||
1278 | PASCListEntry += sizeof(struct HW_SCATTER_GATHER_ELEMENT); | ||
1279 | |||
1280 | #if NUM_SCATTER_GATHER_ENTRIES > 1 | ||
1281 | for (j = 0; j < NUM_SCATTER_GATHER_ENTRIES - 1; j++) { | ||
1282 | SCListEntry->Address = of; | ||
1283 | SCListEntry->Length = OVERFLOW_BUFFER_SIZE; | ||
1284 | SCListEntry += 1; | ||
1285 | PASCListEntry += | ||
1286 | sizeof(struct HW_SCATTER_GATHER_ELEMENT); | ||
1287 | } | ||
1288 | #endif | ||
1289 | |||
1290 | } | ||
1291 | |||
1292 | return status; | ||
1293 | } | ||
1294 | |||
1295 | static int FillTSIdleBuffer(struct SRingBufferDescriptor *pIdleBuffer, | ||
1296 | struct SRingBufferDescriptor *pRingBuffer) | ||
1297 | { | ||
1298 | int status = 0; | ||
1299 | |||
1300 | /* Copy pointer to scatter gather list in TSRingbuffer | ||
1301 | structure for buffer 2 | ||
1302 | Load number of buffer | ||
1303 | */ | ||
1304 | u32 n = pRingBuffer->NumBuffers; | ||
1305 | |||
1306 | /* Point to first buffer entry */ | ||
1307 | struct SBufferHeader *Cur = pRingBuffer->Head; | ||
1308 | int i; | ||
1309 | /* Loop thru all buffer and set Buffer 2 pointers to TSIdlebuffer */ | ||
1310 | for (i = 0; i < n; i++) { | ||
1311 | Cur->Buffer2 = pIdleBuffer->Head->Buffer1; | ||
1312 | Cur->scList2 = pIdleBuffer->Head->scList1; | ||
1313 | Cur->ngeneBuffer.Address_of_first_entry_2 = | ||
1314 | pIdleBuffer->Head->ngeneBuffer. | ||
1315 | Address_of_first_entry_1; | ||
1316 | Cur->ngeneBuffer.Number_of_entries_2 = | ||
1317 | pIdleBuffer->Head->ngeneBuffer.Number_of_entries_1; | ||
1318 | Cur = Cur->Next; | ||
1319 | } | ||
1320 | return status; | ||
1321 | } | ||
1322 | |||
1323 | static u32 RingBufferSizes[MAX_STREAM] = { | ||
1324 | RING_SIZE_VIDEO, | ||
1325 | RING_SIZE_VIDEO, | ||
1326 | RING_SIZE_AUDIO, | ||
1327 | RING_SIZE_AUDIO, | ||
1328 | RING_SIZE_AUDIO, | ||
1329 | }; | ||
1330 | |||
1331 | static u32 Buffer1Sizes[MAX_STREAM] = { | ||
1332 | MAX_VIDEO_BUFFER_SIZE, | ||
1333 | MAX_VIDEO_BUFFER_SIZE, | ||
1334 | MAX_AUDIO_BUFFER_SIZE, | ||
1335 | MAX_AUDIO_BUFFER_SIZE, | ||
1336 | MAX_AUDIO_BUFFER_SIZE | ||
1337 | }; | ||
1338 | |||
1339 | static u32 Buffer2Sizes[MAX_STREAM] = { | ||
1340 | MAX_VBI_BUFFER_SIZE, | ||
1341 | MAX_VBI_BUFFER_SIZE, | ||
1342 | 0, | ||
1343 | 0, | ||
1344 | 0 | ||
1345 | }; | ||
1346 | |||
1347 | |||
1348 | static int AllocCommonBuffers(struct ngene *dev) | ||
1349 | { | ||
1350 | int status = 0, i; | ||
1351 | |||
1352 | dev->FWInterfaceBuffer = pci_alloc_consistent(dev->pci_dev, 4096, | ||
1353 | &dev->PAFWInterfaceBuffer); | ||
1354 | if (!dev->FWInterfaceBuffer) | ||
1355 | return -ENOMEM; | ||
1356 | dev->hosttongene = dev->FWInterfaceBuffer; | ||
1357 | dev->ngenetohost = dev->FWInterfaceBuffer + 256; | ||
1358 | dev->EventBuffer = dev->FWInterfaceBuffer + 512; | ||
1359 | |||
1360 | dev->OverflowBuffer = pci_alloc_consistent(dev->pci_dev, | ||
1361 | OVERFLOW_BUFFER_SIZE, | ||
1362 | &dev->PAOverflowBuffer); | ||
1363 | if (!dev->OverflowBuffer) | ||
1364 | return -ENOMEM; | ||
1365 | memset(dev->OverflowBuffer, 0, OVERFLOW_BUFFER_SIZE); | ||
1366 | |||
1367 | for (i = STREAM_VIDEOIN1; i < MAX_STREAM; i++) { | ||
1368 | int type = dev->card_info->io_type[i]; | ||
1369 | |||
1370 | dev->channel[i].State = KSSTATE_STOP; | ||
1371 | |||
1372 | if (type & (NGENE_IO_TV | NGENE_IO_HDTV | NGENE_IO_AIN)) { | ||
1373 | status = create_ring_buffer(dev->pci_dev, | ||
1374 | &dev->channel[i].RingBuffer, | ||
1375 | RingBufferSizes[i]); | ||
1376 | if (status < 0) | ||
1377 | break; | ||
1378 | |||
1379 | if (type & (NGENE_IO_TV | NGENE_IO_AIN)) { | ||
1380 | status = AllocateRingBuffers(dev->pci_dev, | ||
1381 | dev-> | ||
1382 | PAOverflowBuffer, | ||
1383 | &dev->channel[i]. | ||
1384 | RingBuffer, | ||
1385 | Buffer1Sizes[i], | ||
1386 | Buffer2Sizes[i]); | ||
1387 | if (status < 0) | ||
1388 | break; | ||
1389 | } else if (type & NGENE_IO_HDTV) { | ||
1390 | status = AllocateRingBuffers(dev->pci_dev, | ||
1391 | dev-> | ||
1392 | PAOverflowBuffer, | ||
1393 | &dev->channel[i]. | ||
1394 | RingBuffer, | ||
1395 | MAX_HDTV_BUFFER_SIZE, | ||
1396 | 0); | ||
1397 | if (status < 0) | ||
1398 | break; | ||
1399 | } | ||
1400 | } | ||
1401 | |||
1402 | if (type & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) { | ||
1403 | |||
1404 | status = create_ring_buffer(dev->pci_dev, | ||
1405 | &dev->channel[i]. | ||
1406 | TSRingBuffer, RING_SIZE_TS); | ||
1407 | if (status < 0) | ||
1408 | break; | ||
1409 | |||
1410 | status = AllocateRingBuffers(dev->pci_dev, | ||
1411 | dev->PAOverflowBuffer, | ||
1412 | &dev->channel[i]. | ||
1413 | TSRingBuffer, | ||
1414 | MAX_TS_BUFFER_SIZE, 0); | ||
1415 | if (status) | ||
1416 | break; | ||
1417 | } | ||
1418 | |||
1419 | if (type & NGENE_IO_TSOUT) { | ||
1420 | status = create_ring_buffer(dev->pci_dev, | ||
1421 | &dev->channel[i]. | ||
1422 | TSIdleBuffer, 1); | ||
1423 | if (status < 0) | ||
1424 | break; | ||
1425 | status = AllocateRingBuffers(dev->pci_dev, | ||
1426 | dev->PAOverflowBuffer, | ||
1427 | &dev->channel[i]. | ||
1428 | TSIdleBuffer, | ||
1429 | MAX_TS_BUFFER_SIZE, 0); | ||
1430 | if (status) | ||
1431 | break; | ||
1432 | FillTSIdleBuffer(&dev->channel[i].TSIdleBuffer, | ||
1433 | &dev->channel[i].TSRingBuffer); | ||
1434 | } | ||
1435 | } | ||
1436 | return status; | ||
1437 | } | ||
1438 | |||
1439 | static void ngene_release_buffers(struct ngene *dev) | ||
1440 | { | ||
1441 | if (dev->iomem) | ||
1442 | iounmap(dev->iomem); | ||
1443 | free_common_buffers(dev); | ||
1444 | vfree(dev->tsout_buf); | ||
1445 | vfree(dev->ain_buf); | ||
1446 | vfree(dev->vin_buf); | ||
1447 | vfree(dev); | ||
1448 | } | ||
1449 | |||
1450 | static int ngene_get_buffers(struct ngene *dev) | ||
1451 | { | ||
1452 | if (AllocCommonBuffers(dev)) | ||
1453 | return -ENOMEM; | ||
1454 | if (dev->card_info->io_type[4] & NGENE_IO_TSOUT) { | ||
1455 | dev->tsout_buf = vmalloc(TSOUT_BUF_SIZE); | ||
1456 | if (!dev->tsout_buf) | ||
1457 | return -ENOMEM; | ||
1458 | dvb_ringbuffer_init(&dev->tsout_rbuf, | ||
1459 | dev->tsout_buf, TSOUT_BUF_SIZE); | ||
1460 | } | ||
1461 | if (dev->card_info->io_type[2] & NGENE_IO_AIN) { | ||
1462 | dev->ain_buf = vmalloc(AIN_BUF_SIZE); | ||
1463 | if (!dev->ain_buf) | ||
1464 | return -ENOMEM; | ||
1465 | dvb_ringbuffer_init(&dev->ain_rbuf, dev->ain_buf, AIN_BUF_SIZE); | ||
1466 | } | ||
1467 | if (dev->card_info->io_type[0] & NGENE_IO_HDTV) { | ||
1468 | dev->vin_buf = vmalloc(VIN_BUF_SIZE); | ||
1469 | if (!dev->vin_buf) | ||
1470 | return -ENOMEM; | ||
1471 | dvb_ringbuffer_init(&dev->vin_rbuf, dev->vin_buf, VIN_BUF_SIZE); | ||
1472 | } | ||
1473 | dev->iomem = ioremap(pci_resource_start(dev->pci_dev, 0), | ||
1474 | pci_resource_len(dev->pci_dev, 0)); | ||
1475 | if (!dev->iomem) | ||
1476 | return -ENOMEM; | ||
1477 | |||
1478 | return 0; | ||
1479 | } | ||
1480 | |||
1481 | static void ngene_init(struct ngene *dev) | ||
1482 | { | ||
1483 | int i; | ||
1484 | |||
1485 | tasklet_init(&dev->event_tasklet, event_tasklet, (unsigned long)dev); | ||
1486 | |||
1487 | memset_io(dev->iomem + 0xc000, 0x00, 0x220); | ||
1488 | memset_io(dev->iomem + 0xc400, 0x00, 0x100); | ||
1489 | |||
1490 | for (i = 0; i < MAX_STREAM; i++) { | ||
1491 | dev->channel[i].dev = dev; | ||
1492 | dev->channel[i].number = i; | ||
1493 | } | ||
1494 | |||
1495 | dev->fw_interface_version = 0; | ||
1496 | |||
1497 | ngwritel(0, NGENE_INT_ENABLE); | ||
1498 | |||
1499 | dev->icounts = ngreadl(NGENE_INT_COUNTS); | ||
1500 | |||
1501 | dev->device_version = ngreadl(DEV_VER) & 0x0f; | ||
1502 | printk(KERN_INFO DEVICE_NAME ": Device version %d\n", | ||
1503 | dev->device_version); | ||
1504 | } | ||
1505 | |||
1506 | static int ngene_load_firm(struct ngene *dev) | ||
1507 | { | ||
1508 | u32 size; | ||
1509 | const struct firmware *fw = NULL; | ||
1510 | u8 *ngene_fw; | ||
1511 | char *fw_name; | ||
1512 | int err, version; | ||
1513 | |||
1514 | version = dev->card_info->fw_version; | ||
1515 | |||
1516 | switch (version) { | ||
1517 | default: | ||
1518 | case 15: | ||
1519 | version = 15; | ||
1520 | size = 23466; | ||
1521 | fw_name = "ngene_15.fw"; | ||
1522 | break; | ||
1523 | case 16: | ||
1524 | size = 23498; | ||
1525 | fw_name = "ngene_16.fw"; | ||
1526 | break; | ||
1527 | case 17: | ||
1528 | size = 24446; | ||
1529 | fw_name = "ngene_17.fw"; | ||
1530 | break; | ||
1531 | } | ||
1532 | |||
1533 | if (request_firmware(&fw, fw_name, &dev->pci_dev->dev) < 0) { | ||
1534 | printk(KERN_ERR DEVICE_NAME | ||
1535 | ": Could not load firmware file %s.\n", fw_name); | ||
1536 | printk(KERN_INFO DEVICE_NAME | ||
1537 | ": Copy %s to your hotplug directory!\n", fw_name); | ||
1538 | return -1; | ||
1539 | } | ||
1540 | if (size != fw->size) { | ||
1541 | printk(KERN_ERR DEVICE_NAME | ||
1542 | ": Firmware %s has invalid size!", fw_name); | ||
1543 | err = -1; | ||
1544 | } else { | ||
1545 | printk(KERN_INFO DEVICE_NAME | ||
1546 | ": Loading firmware file %s.\n", fw_name); | ||
1547 | ngene_fw = (u8 *) fw->data; | ||
1548 | err = ngene_command_load_firmware(dev, ngene_fw, size); | ||
1549 | } | ||
1550 | |||
1551 | release_firmware(fw); | ||
1552 | |||
1553 | return err; | ||
1554 | } | ||
1555 | |||
1556 | static void ngene_stop(struct ngene *dev) | ||
1557 | { | ||
1558 | down(&dev->cmd_mutex); | ||
1559 | i2c_del_adapter(&(dev->channel[0].i2c_adapter)); | ||
1560 | i2c_del_adapter(&(dev->channel[1].i2c_adapter)); | ||
1561 | ngwritel(0, NGENE_INT_ENABLE); | ||
1562 | ngwritel(0, NGENE_COMMAND); | ||
1563 | ngwritel(0, NGENE_COMMAND_HI); | ||
1564 | ngwritel(0, NGENE_STATUS); | ||
1565 | ngwritel(0, NGENE_STATUS_HI); | ||
1566 | ngwritel(0, NGENE_EVENT); | ||
1567 | ngwritel(0, NGENE_EVENT_HI); | ||
1568 | free_irq(dev->pci_dev->irq, dev); | ||
1569 | } | ||
1570 | |||
1571 | static int ngene_start(struct ngene *dev) | ||
1572 | { | ||
1573 | int stat; | ||
1574 | int i; | ||
1575 | |||
1576 | pci_set_master(dev->pci_dev); | ||
1577 | ngene_init(dev); | ||
1578 | |||
1579 | stat = request_irq(dev->pci_dev->irq, irq_handler, | ||
1580 | IRQF_SHARED, "nGene", | ||
1581 | (void *)dev); | ||
1582 | if (stat < 0) | ||
1583 | return stat; | ||
1584 | |||
1585 | init_waitqueue_head(&dev->cmd_wq); | ||
1586 | init_waitqueue_head(&dev->tx_wq); | ||
1587 | init_waitqueue_head(&dev->rx_wq); | ||
1588 | sema_init(&dev->cmd_mutex, 1); | ||
1589 | sema_init(&dev->stream_mutex, 1); | ||
1590 | sema_init(&dev->pll_mutex, 1); | ||
1591 | sema_init(&dev->i2c_switch_mutex, 1); | ||
1592 | spin_lock_init(&dev->cmd_lock); | ||
1593 | for (i = 0; i < MAX_STREAM; i++) | ||
1594 | spin_lock_init(&dev->channel[i].state_lock); | ||
1595 | ngwritel(1, TIMESTAMPS); | ||
1596 | |||
1597 | ngwritel(1, NGENE_INT_ENABLE); | ||
1598 | |||
1599 | stat = ngene_load_firm(dev); | ||
1600 | if (stat < 0) | ||
1601 | goto fail; | ||
1602 | |||
1603 | stat = ngene_i2c_init(dev, 0); | ||
1604 | if (stat < 0) | ||
1605 | goto fail; | ||
1606 | |||
1607 | stat = ngene_i2c_init(dev, 1); | ||
1608 | if (stat < 0) | ||
1609 | goto fail; | ||
1610 | |||
1611 | if (dev->card_info->fw_version == 17) { | ||
1612 | u8 tsin4_config[6] = { | ||
1613 | 3072 / 64, 3072 / 64, 0, 3072 / 64, 3072 / 64, 0}; | ||
1614 | u8 default_config[6] = { | ||
1615 | 4096 / 64, 4096 / 64, 0, 2048 / 64, 2048 / 64, 0}; | ||
1616 | u8 *bconf = default_config; | ||
1617 | |||
1618 | if (dev->card_info->io_type[3] == NGENE_IO_TSIN) | ||
1619 | bconf = tsin4_config; | ||
1620 | dprintk(KERN_DEBUG DEVICE_NAME ": FW 17 buffer config\n"); | ||
1621 | stat = ngene_command_config_free_buf(dev, bconf); | ||
1622 | } else { | ||
1623 | int bconf = BUFFER_CONFIG_4422; | ||
1624 | if (dev->card_info->io_type[3] == NGENE_IO_TSIN) | ||
1625 | bconf = BUFFER_CONFIG_3333; | ||
1626 | stat = ngene_command_config_buf(dev, bconf); | ||
1627 | } | ||
1628 | return stat; | ||
1629 | fail: | ||
1630 | ngwritel(0, NGENE_INT_ENABLE); | ||
1631 | free_irq(dev->pci_dev->irq, dev); | ||
1632 | return stat; | ||
1633 | } | ||
1634 | |||
1635 | |||
1636 | |||
1637 | /****************************************************************************/ | ||
1638 | /* Switch control (I2C gates, etc.) *****************************************/ | ||
1639 | /****************************************************************************/ | ||
1640 | |||
1641 | |||
1642 | /****************************************************************************/ | ||
1643 | /* Demod/tuner attachment ***************************************************/ | ||
1644 | /****************************************************************************/ | ||
1645 | |||
1646 | static int tuner_attach_stv6110(struct ngene_channel *chan) | ||
1647 | { | ||
1648 | struct stv090x_config *feconf = (struct stv090x_config *) | ||
1649 | chan->dev->card_info->fe_config[chan->number]; | ||
1650 | struct stv6110x_config *tunerconf = (struct stv6110x_config *) | ||
1651 | chan->dev->card_info->tuner_config[chan->number]; | ||
1652 | struct stv6110x_devctl *ctl; | ||
1653 | |||
1654 | ctl = dvb_attach(stv6110x_attach, chan->fe, tunerconf, | ||
1655 | &chan->i2c_adapter); | ||
1656 | if (ctl == NULL) { | ||
1657 | printk(KERN_ERR DEVICE_NAME ": No STV6110X found!\n"); | ||
1658 | return -ENODEV; | ||
1659 | } | ||
1660 | |||
1661 | feconf->tuner_init = ctl->tuner_init; | ||
1662 | feconf->tuner_set_mode = ctl->tuner_set_mode; | ||
1663 | feconf->tuner_set_frequency = ctl->tuner_set_frequency; | ||
1664 | feconf->tuner_get_frequency = ctl->tuner_get_frequency; | ||
1665 | feconf->tuner_set_bandwidth = ctl->tuner_set_bandwidth; | ||
1666 | feconf->tuner_get_bandwidth = ctl->tuner_get_bandwidth; | ||
1667 | feconf->tuner_set_bbgain = ctl->tuner_set_bbgain; | ||
1668 | feconf->tuner_get_bbgain = ctl->tuner_get_bbgain; | ||
1669 | feconf->tuner_set_refclk = ctl->tuner_set_refclk; | ||
1670 | feconf->tuner_get_status = ctl->tuner_get_status; | ||
1671 | |||
1672 | return 0; | ||
1673 | } | ||
1674 | |||
1675 | |||
1676 | static int demod_attach_stv0900(struct ngene_channel *chan) | ||
1677 | { | ||
1678 | struct stv090x_config *feconf = (struct stv090x_config *) | ||
1679 | chan->dev->card_info->fe_config[chan->number]; | ||
1680 | |||
1681 | chan->fe = dvb_attach(stv090x_attach, | ||
1682 | feconf, | ||
1683 | &chan->i2c_adapter, | ||
1684 | chan->number == 0 ? STV090x_DEMODULATOR_0 : | ||
1685 | STV090x_DEMODULATOR_1); | ||
1686 | if (chan->fe == NULL) { | ||
1687 | printk(KERN_ERR DEVICE_NAME ": No STV0900 found!\n"); | ||
1688 | return -ENODEV; | ||
1689 | } | ||
1690 | |||
1691 | if (!dvb_attach(lnbh24_attach, chan->fe, &chan->i2c_adapter, 0, | ||
1692 | 0, chan->dev->card_info->lnb[chan->number])) { | ||
1693 | printk(KERN_ERR DEVICE_NAME ": No LNBH24 found!\n"); | ||
1694 | dvb_frontend_detach(chan->fe); | ||
1695 | return -ENODEV; | ||
1696 | } | ||
1697 | |||
1698 | return 0; | ||
1699 | } | ||
1700 | |||
1701 | /****************************************************************************/ | ||
1702 | /****************************************************************************/ | ||
1703 | /****************************************************************************/ | ||
1704 | |||
1705 | static void release_channel(struct ngene_channel *chan) | ||
1706 | { | ||
1707 | struct dvb_demux *dvbdemux = &chan->demux; | ||
1708 | struct ngene *dev = chan->dev; | ||
1709 | struct ngene_info *ni = dev->card_info; | ||
1710 | int io = ni->io_type[chan->number]; | ||
1711 | |||
1712 | #ifdef COMMAND_TIMEOUT_WORKAROUND | ||
1713 | if (chan->running) | ||
1714 | set_transfer(chan, 0); | ||
1715 | #endif | ||
1716 | |||
1717 | tasklet_kill(&chan->demux_tasklet); | ||
1718 | |||
1719 | if (io & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) { | ||
1720 | if (chan->fe) { | ||
1721 | dvb_unregister_frontend(chan->fe); | ||
1722 | dvb_frontend_detach(chan->fe); | ||
1723 | chan->fe = 0; | ||
1724 | } | ||
1725 | dvbdemux->dmx.close(&dvbdemux->dmx); | ||
1726 | dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, | ||
1727 | &chan->hw_frontend); | ||
1728 | dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, | ||
1729 | &chan->mem_frontend); | ||
1730 | dvb_dmxdev_release(&chan->dmxdev); | ||
1731 | dvb_dmx_release(&chan->demux); | ||
1732 | |||
1733 | if (chan->number == 0 || !one_adapter) | ||
1734 | dvb_unregister_adapter(&dev->adapter[chan->number]); | ||
1735 | } | ||
1736 | } | ||
1737 | |||
1738 | static int init_channel(struct ngene_channel *chan) | ||
1739 | { | ||
1740 | int ret = 0, nr = chan->number; | ||
1741 | struct dvb_adapter *adapter = NULL; | ||
1742 | struct dvb_demux *dvbdemux = &chan->demux; | ||
1743 | struct ngene *dev = chan->dev; | ||
1744 | struct ngene_info *ni = dev->card_info; | ||
1745 | int io = ni->io_type[nr]; | ||
1746 | |||
1747 | tasklet_init(&chan->demux_tasklet, demux_tasklet, (unsigned long)chan); | ||
1748 | chan->users = 0; | ||
1749 | chan->type = io; | ||
1750 | chan->mode = chan->type; /* for now only one mode */ | ||
1751 | |||
1752 | if (io & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) { | ||
1753 | if (nr >= STREAM_AUDIOIN1) | ||
1754 | chan->DataFormatFlags = DF_SWAP32; | ||
1755 | if (nr == 0 || !one_adapter) { | ||
1756 | adapter = &dev->adapter[nr]; | ||
1757 | ret = dvb_register_adapter(adapter, "nGene", | ||
1758 | THIS_MODULE, | ||
1759 | &chan->dev->pci_dev->dev, | ||
1760 | adapter_nr); | ||
1761 | if (ret < 0) | ||
1762 | return ret; | ||
1763 | } else { | ||
1764 | adapter = &dev->adapter[0]; | ||
1765 | } | ||
1766 | |||
1767 | ret = my_dvb_dmx_ts_card_init(dvbdemux, "SW demux", | ||
1768 | ngene_start_feed, | ||
1769 | ngene_stop_feed, chan); | ||
1770 | ret = my_dvb_dmxdev_ts_card_init(&chan->dmxdev, &chan->demux, | ||
1771 | &chan->hw_frontend, | ||
1772 | &chan->mem_frontend, adapter); | ||
1773 | } | ||
1774 | |||
1775 | if (io & NGENE_IO_TSIN) { | ||
1776 | chan->fe = NULL; | ||
1777 | if (ni->demod_attach[nr]) | ||
1778 | ni->demod_attach[nr](chan); | ||
1779 | if (chan->fe) { | ||
1780 | if (dvb_register_frontend(adapter, chan->fe) < 0) { | ||
1781 | if (chan->fe->ops.release) | ||
1782 | chan->fe->ops.release(chan->fe); | ||
1783 | chan->fe = NULL; | ||
1784 | } | ||
1785 | } | ||
1786 | if (chan->fe && ni->tuner_attach[nr]) | ||
1787 | if (ni->tuner_attach[nr] (chan) < 0) { | ||
1788 | printk(KERN_ERR DEVICE_NAME | ||
1789 | ": Tuner attach failed on channel %d!\n", | ||
1790 | nr); | ||
1791 | } | ||
1792 | } | ||
1793 | return ret; | ||
1794 | } | ||
1795 | |||
1796 | static int init_channels(struct ngene *dev) | ||
1797 | { | ||
1798 | int i, j; | ||
1799 | |||
1800 | for (i = 0; i < MAX_STREAM; i++) { | ||
1801 | if (init_channel(&dev->channel[i]) < 0) { | ||
1802 | for (j = i - 1; j >= 0; j--) | ||
1803 | release_channel(&dev->channel[j]); | ||
1804 | return -1; | ||
1805 | } | ||
1806 | } | ||
1807 | return 0; | ||
1808 | } | ||
1809 | |||
1810 | /****************************************************************************/ | ||
1811 | /* device probe/remove calls ************************************************/ | ||
1812 | /****************************************************************************/ | ||
1813 | |||
1814 | static void __devexit ngene_remove(struct pci_dev *pdev) | ||
1815 | { | ||
1816 | struct ngene *dev = (struct ngene *)pci_get_drvdata(pdev); | ||
1817 | int i; | ||
1818 | |||
1819 | tasklet_kill(&dev->event_tasklet); | ||
1820 | for (i = MAX_STREAM - 1; i >= 0; i--) | ||
1821 | release_channel(&dev->channel[i]); | ||
1822 | ngene_stop(dev); | ||
1823 | ngene_release_buffers(dev); | ||
1824 | pci_set_drvdata(pdev, 0); | ||
1825 | pci_disable_device(pdev); | ||
1826 | } | ||
1827 | |||
1828 | static int __devinit ngene_probe(struct pci_dev *pci_dev, | ||
1829 | const struct pci_device_id *id) | ||
1830 | { | ||
1831 | struct ngene *dev; | ||
1832 | int stat = 0; | ||
1833 | |||
1834 | if (pci_enable_device(pci_dev) < 0) | ||
1835 | return -ENODEV; | ||
1836 | |||
1837 | dev = vmalloc(sizeof(struct ngene)); | ||
1838 | if (dev == NULL) { | ||
1839 | stat = -ENOMEM; | ||
1840 | goto fail0; | ||
1841 | } | ||
1842 | memset(dev, 0, sizeof(struct ngene)); | ||
1843 | |||
1844 | dev->pci_dev = pci_dev; | ||
1845 | dev->card_info = (struct ngene_info *)id->driver_data; | ||
1846 | printk(KERN_INFO DEVICE_NAME ": Found %s\n", dev->card_info->name); | ||
1847 | |||
1848 | pci_set_drvdata(pci_dev, dev); | ||
1849 | |||
1850 | /* Alloc buffers and start nGene */ | ||
1851 | stat = ngene_get_buffers(dev); | ||
1852 | if (stat < 0) | ||
1853 | goto fail1; | ||
1854 | stat = ngene_start(dev); | ||
1855 | if (stat < 0) | ||
1856 | goto fail1; | ||
1857 | |||
1858 | dev->i2c_current_bus = -1; | ||
1859 | |||
1860 | /* Register DVB adapters and devices for both channels */ | ||
1861 | if (init_channels(dev) < 0) | ||
1862 | goto fail2; | ||
1863 | |||
1864 | return 0; | ||
1865 | |||
1866 | fail2: | ||
1867 | ngene_stop(dev); | ||
1868 | fail1: | ||
1869 | ngene_release_buffers(dev); | ||
1870 | fail0: | ||
1871 | pci_disable_device(pci_dev); | ||
1872 | pci_set_drvdata(pci_dev, 0); | ||
1873 | return stat; | ||
1874 | } | ||
1875 | |||
1876 | /****************************************************************************/ | ||
1877 | /* Card configs *************************************************************/ | ||
1878 | /****************************************************************************/ | ||
1879 | |||
1880 | static struct stv090x_config fe_cineS2 = { | ||
1881 | .device = STV0900, | ||
1882 | .demod_mode = STV090x_DUAL, | ||
1883 | .clk_mode = STV090x_CLK_EXT, | ||
1884 | |||
1885 | .xtal = 27000000, | ||
1886 | .address = 0x68, | ||
1887 | |||
1888 | .ts1_mode = STV090x_TSMODE_SERIAL_PUNCTURED, | ||
1889 | .ts2_mode = STV090x_TSMODE_SERIAL_PUNCTURED, | ||
1890 | |||
1891 | .repeater_level = STV090x_RPTLEVEL_16, | ||
1892 | |||
1893 | .adc1_range = STV090x_ADC_1Vpp, | ||
1894 | .adc2_range = STV090x_ADC_1Vpp, | ||
1895 | |||
1896 | .diseqc_envelope_mode = true, | ||
1897 | }; | ||
1898 | |||
1899 | static struct stv6110x_config tuner_cineS2_0 = { | ||
1900 | .addr = 0x60, | ||
1901 | .refclk = 27000000, | ||
1902 | .clk_div = 1, | ||
1903 | }; | ||
1904 | |||
1905 | static struct stv6110x_config tuner_cineS2_1 = { | ||
1906 | .addr = 0x63, | ||
1907 | .refclk = 27000000, | ||
1908 | .clk_div = 1, | ||
1909 | }; | ||
1910 | |||
1911 | static struct ngene_info ngene_info_cineS2 = { | ||
1912 | .type = NGENE_SIDEWINDER, | ||
1913 | .name = "Linux4Media cineS2 DVB-S2 Twin Tuner", | ||
1914 | .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN}, | ||
1915 | .demod_attach = {demod_attach_stv0900, demod_attach_stv0900}, | ||
1916 | .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110}, | ||
1917 | .fe_config = {&fe_cineS2, &fe_cineS2}, | ||
1918 | .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1}, | ||
1919 | .lnb = {0x0b, 0x08}, | ||
1920 | .tsf = {3, 3}, | ||
1921 | .fw_version = 15, | ||
1922 | }; | ||
1923 | |||
1924 | static struct ngene_info ngene_info_satixs2 = { | ||
1925 | .type = NGENE_SIDEWINDER, | ||
1926 | .name = "Mystique SaTiX-S2 Dual", | ||
1927 | .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN}, | ||
1928 | .demod_attach = {demod_attach_stv0900, demod_attach_stv0900}, | ||
1929 | .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110}, | ||
1930 | .fe_config = {&fe_cineS2, &fe_cineS2}, | ||
1931 | .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1}, | ||
1932 | .lnb = {0x0b, 0x08}, | ||
1933 | .tsf = {3, 3}, | ||
1934 | .fw_version = 15, | ||
1935 | }; | ||
1936 | |||
1937 | /****************************************************************************/ | ||
1938 | |||
1939 | |||
1940 | |||
1941 | /****************************************************************************/ | ||
1942 | /* PCI Subsystem ID *********************************************************/ | ||
1943 | /****************************************************************************/ | ||
1944 | |||
1945 | #define NGENE_ID(_subvend, _subdev, _driverdata) { \ | ||
1946 | .vendor = NGENE_VID, .device = NGENE_PID, \ | ||
1947 | .subvendor = _subvend, .subdevice = _subdev, \ | ||
1948 | .driver_data = (unsigned long) &_driverdata } | ||
1949 | |||
1950 | /****************************************************************************/ | ||
1951 | |||
1952 | static const struct pci_device_id ngene_id_tbl[] __devinitdata = { | ||
1953 | NGENE_ID(0x18c3, 0xabc3, ngene_info_cineS2), | ||
1954 | NGENE_ID(0x18c3, 0xabc4, ngene_info_cineS2), | ||
1955 | NGENE_ID(0x18c3, 0xdb01, ngene_info_satixs2), | ||
1956 | {0} | ||
1957 | }; | ||
1958 | MODULE_DEVICE_TABLE(pci, ngene_id_tbl); | ||
1959 | |||
1960 | /****************************************************************************/ | ||
1961 | /* Init/Exit ****************************************************************/ | ||
1962 | /****************************************************************************/ | ||
1963 | |||
1964 | static pci_ers_result_t ngene_error_detected(struct pci_dev *dev, | ||
1965 | enum pci_channel_state state) | ||
1966 | { | ||
1967 | printk(KERN_ERR DEVICE_NAME ": PCI error\n"); | ||
1968 | if (state == pci_channel_io_perm_failure) | ||
1969 | return PCI_ERS_RESULT_DISCONNECT; | ||
1970 | if (state == pci_channel_io_frozen) | ||
1971 | return PCI_ERS_RESULT_NEED_RESET; | ||
1972 | return PCI_ERS_RESULT_CAN_RECOVER; | ||
1973 | } | ||
1974 | |||
1975 | static pci_ers_result_t ngene_link_reset(struct pci_dev *dev) | ||
1976 | { | ||
1977 | printk(KERN_INFO DEVICE_NAME ": link reset\n"); | ||
1978 | return 0; | ||
1979 | } | ||
1980 | |||
1981 | static pci_ers_result_t ngene_slot_reset(struct pci_dev *dev) | ||
1982 | { | ||
1983 | printk(KERN_INFO DEVICE_NAME ": slot reset\n"); | ||
1984 | return 0; | ||
1985 | } | ||
1986 | |||
1987 | static void ngene_resume(struct pci_dev *dev) | ||
1988 | { | ||
1989 | printk(KERN_INFO DEVICE_NAME ": resume\n"); | ||
1990 | } | ||
1991 | |||
1992 | static struct pci_error_handlers ngene_errors = { | ||
1993 | .error_detected = ngene_error_detected, | ||
1994 | .link_reset = ngene_link_reset, | ||
1995 | .slot_reset = ngene_slot_reset, | ||
1996 | .resume = ngene_resume, | ||
1997 | }; | ||
1998 | |||
1999 | static struct pci_driver ngene_pci_driver = { | ||
2000 | .name = "ngene", | ||
2001 | .id_table = ngene_id_tbl, | ||
2002 | .probe = ngene_probe, | ||
2003 | .remove = __devexit_p(ngene_remove), | ||
2004 | .err_handler = &ngene_errors, | ||
2005 | }; | ||
2006 | |||
2007 | static __init int module_init_ngene(void) | ||
2008 | { | ||
2009 | printk(KERN_INFO | ||
2010 | "nGene PCIE bridge driver, Copyright (C) 2005-2007 Micronas\n"); | ||
2011 | return pci_register_driver(&ngene_pci_driver); | ||
2012 | } | ||
2013 | |||
2014 | static __exit void module_exit_ngene(void) | ||
2015 | { | ||
2016 | pci_unregister_driver(&ngene_pci_driver); | ||
2017 | } | ||
2018 | |||
2019 | module_init(module_init_ngene); | ||
2020 | module_exit(module_exit_ngene); | ||
2021 | |||
2022 | MODULE_DESCRIPTION("nGene"); | ||
2023 | MODULE_AUTHOR("Micronas, Ralph Metzler, Manfred Voelkel"); | ||
2024 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/ngene/ngene.h b/drivers/media/dvb/ngene/ngene.h new file mode 100644 index 000000000000..a7eb29846310 --- /dev/null +++ b/drivers/media/dvb/ngene/ngene.h | |||
@@ -0,0 +1,859 @@ | |||
1 | /* | ||
2 | * ngene.h: nGene PCIe bridge driver | ||
3 | * | ||
4 | * Copyright (C) 2005-2007 Micronas | ||
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 | * version 2 only, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
20 | * 02110-1301, USA | ||
21 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||
22 | */ | ||
23 | |||
24 | #ifndef _NGENE_H_ | ||
25 | #define _NGENE_H_ | ||
26 | |||
27 | #include <linux/types.h> | ||
28 | #include <linux/sched.h> | ||
29 | #include <linux/interrupt.h> | ||
30 | #include <linux/i2c.h> | ||
31 | #include <asm/dma.h> | ||
32 | #include <linux/scatterlist.h> | ||
33 | |||
34 | #include <linux/dvb/frontend.h> | ||
35 | |||
36 | #include "dmxdev.h" | ||
37 | #include "dvbdev.h" | ||
38 | #include "dvb_demux.h" | ||
39 | #include "dvb_frontend.h" | ||
40 | #include "dvb_ringbuffer.h" | ||
41 | |||
42 | #define NGENE_VID 0x18c3 | ||
43 | #define NGENE_PID 0x0720 | ||
44 | |||
45 | #ifndef VIDEO_CAP_VC1 | ||
46 | #define VIDEO_CAP_AVC 128 | ||
47 | #define VIDEO_CAP_H264 128 | ||
48 | #define VIDEO_CAP_VC1 256 | ||
49 | #define VIDEO_CAP_WMV9 256 | ||
50 | #define VIDEO_CAP_MPEG4 512 | ||
51 | #endif | ||
52 | |||
53 | enum STREAM { | ||
54 | STREAM_VIDEOIN1 = 0, /* ITU656 or TS Input */ | ||
55 | STREAM_VIDEOIN2, | ||
56 | STREAM_AUDIOIN1, /* I2S or SPI Input */ | ||
57 | STREAM_AUDIOIN2, | ||
58 | STREAM_AUDIOOUT, | ||
59 | MAX_STREAM | ||
60 | }; | ||
61 | |||
62 | enum SMODE_BITS { | ||
63 | SMODE_AUDIO_SPDIF = 0x20, | ||
64 | SMODE_AVSYNC = 0x10, | ||
65 | SMODE_TRANSPORT_STREAM = 0x08, | ||
66 | SMODE_AUDIO_CAPTURE = 0x04, | ||
67 | SMODE_VBI_CAPTURE = 0x02, | ||
68 | SMODE_VIDEO_CAPTURE = 0x01 | ||
69 | }; | ||
70 | |||
71 | enum STREAM_FLAG_BITS { | ||
72 | SFLAG_CHROMA_FORMAT_2COMP = 0x01, /* Chroma Format : 2's complement */ | ||
73 | SFLAG_CHROMA_FORMAT_OFFSET = 0x00, /* Chroma Format : Binary offset */ | ||
74 | SFLAG_ORDER_LUMA_CHROMA = 0x02, /* Byte order: Y,Cb,Y,Cr */ | ||
75 | SFLAG_ORDER_CHROMA_LUMA = 0x00, /* Byte order: Cb,Y,Cr,Y */ | ||
76 | SFLAG_COLORBAR = 0x04, /* Select colorbar */ | ||
77 | }; | ||
78 | |||
79 | #define PROGRAM_ROM 0x0000 | ||
80 | #define PROGRAM_SRAM 0x1000 | ||
81 | #define PERIPHERALS0 0x8000 | ||
82 | #define PERIPHERALS1 0x9000 | ||
83 | #define SHARED_BUFFER 0xC000 | ||
84 | |||
85 | #define HOST_TO_NGENE (SHARED_BUFFER+0x0000) | ||
86 | #define NGENE_TO_HOST (SHARED_BUFFER+0x0100) | ||
87 | #define NGENE_COMMAND (SHARED_BUFFER+0x0200) | ||
88 | #define NGENE_COMMAND_HI (SHARED_BUFFER+0x0204) | ||
89 | #define NGENE_STATUS (SHARED_BUFFER+0x0208) | ||
90 | #define NGENE_STATUS_HI (SHARED_BUFFER+0x020C) | ||
91 | #define NGENE_EVENT (SHARED_BUFFER+0x0210) | ||
92 | #define NGENE_EVENT_HI (SHARED_BUFFER+0x0214) | ||
93 | #define VARIABLES (SHARED_BUFFER+0x0210) | ||
94 | |||
95 | #define NGENE_INT_COUNTS (SHARED_BUFFER+0x0260) | ||
96 | #define NGENE_INT_ENABLE (SHARED_BUFFER+0x0264) | ||
97 | #define NGENE_VBI_LINE_COUNT (SHARED_BUFFER+0x0268) | ||
98 | |||
99 | #define BUFFER_GP_XMIT (SHARED_BUFFER+0x0800) | ||
100 | #define BUFFER_GP_RECV (SHARED_BUFFER+0x0900) | ||
101 | #define EEPROM_AREA (SHARED_BUFFER+0x0A00) | ||
102 | |||
103 | #define SG_V_IN_1 (SHARED_BUFFER+0x0A80) | ||
104 | #define SG_VBI_1 (SHARED_BUFFER+0x0B00) | ||
105 | #define SG_A_IN_1 (SHARED_BUFFER+0x0B80) | ||
106 | #define SG_V_IN_2 (SHARED_BUFFER+0x0C00) | ||
107 | #define SG_VBI_2 (SHARED_BUFFER+0x0C80) | ||
108 | #define SG_A_IN_2 (SHARED_BUFFER+0x0D00) | ||
109 | #define SG_V_OUT (SHARED_BUFFER+0x0D80) | ||
110 | #define SG_A_OUT2 (SHARED_BUFFER+0x0E00) | ||
111 | |||
112 | #define DATA_A_IN_1 (SHARED_BUFFER+0x0E80) | ||
113 | #define DATA_A_IN_2 (SHARED_BUFFER+0x0F00) | ||
114 | #define DATA_A_OUT (SHARED_BUFFER+0x0F80) | ||
115 | #define DATA_V_IN_1 (SHARED_BUFFER+0x1000) | ||
116 | #define DATA_V_IN_2 (SHARED_BUFFER+0x2000) | ||
117 | #define DATA_V_OUT (SHARED_BUFFER+0x3000) | ||
118 | |||
119 | #define DATA_FIFO_AREA (SHARED_BUFFER+0x1000) | ||
120 | |||
121 | #define TIMESTAMPS 0xA000 | ||
122 | #define SCRATCHPAD 0xA080 | ||
123 | #define FORCE_INT 0xA088 | ||
124 | #define FORCE_NMI 0xA090 | ||
125 | #define INT_STATUS 0xA0A0 | ||
126 | |||
127 | #define DEV_VER 0x9004 | ||
128 | |||
129 | #define FW_DEBUG_DEFAULT (PROGRAM_SRAM+0x00FF) | ||
130 | |||
131 | struct SG_ADDR { | ||
132 | u64 start; | ||
133 | u64 curr; | ||
134 | u16 curr_ptr; | ||
135 | u16 elements; | ||
136 | u32 pad[3]; | ||
137 | } __attribute__ ((__packed__)); | ||
138 | |||
139 | struct SHARED_MEMORY { | ||
140 | /* C000 */ | ||
141 | u32 HostToNgene[64]; | ||
142 | |||
143 | /* C100 */ | ||
144 | u32 NgeneToHost[64]; | ||
145 | |||
146 | /* C200 */ | ||
147 | u64 NgeneCommand; | ||
148 | u64 NgeneStatus; | ||
149 | u64 NgeneEvent; | ||
150 | |||
151 | /* C210 */ | ||
152 | u8 pad1[0xc260 - 0xc218]; | ||
153 | |||
154 | /* C260 */ | ||
155 | u32 IntCounts; | ||
156 | u32 IntEnable; | ||
157 | |||
158 | /* C268 */ | ||
159 | u8 pad2[0xd000 - 0xc268]; | ||
160 | |||
161 | } __attribute__ ((__packed__)); | ||
162 | |||
163 | struct BUFFER_STREAM_RESULTS { | ||
164 | u32 Clock; /* Stream time in 100ns units */ | ||
165 | u16 RemainingLines; /* Remaining lines in this field. | ||
166 | 0 for complete field */ | ||
167 | u8 FieldCount; /* Video field number */ | ||
168 | u8 Flags; /* Bit 7 = Done, Bit 6 = seen, Bit 5 = overflow, | ||
169 | Bit 0 = FieldID */ | ||
170 | u16 BlockCount; /* Audio block count (unused) */ | ||
171 | u8 Reserved[2]; | ||
172 | u32 DTOUpdate; | ||
173 | } __attribute__ ((__packed__)); | ||
174 | |||
175 | struct HW_SCATTER_GATHER_ELEMENT { | ||
176 | u64 Address; | ||
177 | u32 Length; | ||
178 | u32 Reserved; | ||
179 | } __attribute__ ((__packed__)); | ||
180 | |||
181 | struct BUFFER_HEADER { | ||
182 | u64 Next; | ||
183 | struct BUFFER_STREAM_RESULTS SR; | ||
184 | |||
185 | u32 Number_of_entries_1; | ||
186 | u32 Reserved5; | ||
187 | u64 Address_of_first_entry_1; | ||
188 | |||
189 | u32 Number_of_entries_2; | ||
190 | u32 Reserved7; | ||
191 | u64 Address_of_first_entry_2; | ||
192 | } __attribute__ ((__packed__)); | ||
193 | |||
194 | struct EVENT_BUFFER { | ||
195 | u32 TimeStamp; | ||
196 | u8 GPIOStatus; | ||
197 | u8 UARTStatus; | ||
198 | u8 RXCharacter; | ||
199 | u8 EventStatus; | ||
200 | u32 Reserved[2]; | ||
201 | } __attribute__ ((__packed__)); | ||
202 | |||
203 | /* Firmware commands. */ | ||
204 | |||
205 | enum OPCODES { | ||
206 | CMD_NOP = 0, | ||
207 | CMD_FWLOAD_PREPARE = 0x01, | ||
208 | CMD_FWLOAD_FINISH = 0x02, | ||
209 | CMD_I2C_READ = 0x03, | ||
210 | CMD_I2C_WRITE = 0x04, | ||
211 | |||
212 | CMD_I2C_WRITE_NOSTOP = 0x05, | ||
213 | CMD_I2C_CONTINUE_WRITE = 0x06, | ||
214 | CMD_I2C_CONTINUE_WRITE_NOSTOP = 0x07, | ||
215 | |||
216 | CMD_DEBUG_OUTPUT = 0x09, | ||
217 | |||
218 | CMD_CONTROL = 0x10, | ||
219 | CMD_CONFIGURE_BUFFER = 0x11, | ||
220 | CMD_CONFIGURE_FREE_BUFFER = 0x12, | ||
221 | |||
222 | CMD_SPI_READ = 0x13, | ||
223 | CMD_SPI_WRITE = 0x14, | ||
224 | |||
225 | CMD_MEM_READ = 0x20, | ||
226 | CMD_MEM_WRITE = 0x21, | ||
227 | CMD_SFR_READ = 0x22, | ||
228 | CMD_SFR_WRITE = 0x23, | ||
229 | CMD_IRAM_READ = 0x24, | ||
230 | CMD_IRAM_WRITE = 0x25, | ||
231 | CMD_SET_GPIO_PIN = 0x26, | ||
232 | CMD_SET_GPIO_INT = 0x27, | ||
233 | CMD_CONFIGURE_UART = 0x28, | ||
234 | CMD_WRITE_UART = 0x29, | ||
235 | MAX_CMD | ||
236 | }; | ||
237 | |||
238 | enum RESPONSES { | ||
239 | OK = 0, | ||
240 | ERROR = 1 | ||
241 | }; | ||
242 | |||
243 | struct FW_HEADER { | ||
244 | u8 Opcode; | ||
245 | u8 Length; | ||
246 | } __attribute__ ((__packed__)); | ||
247 | |||
248 | struct FW_I2C_WRITE { | ||
249 | struct FW_HEADER hdr; | ||
250 | u8 Device; | ||
251 | u8 Data[250]; | ||
252 | } __attribute__ ((__packed__)); | ||
253 | |||
254 | struct FW_I2C_CONTINUE_WRITE { | ||
255 | struct FW_HEADER hdr; | ||
256 | u8 Data[250]; | ||
257 | } __attribute__ ((__packed__)); | ||
258 | |||
259 | struct FW_I2C_READ { | ||
260 | struct FW_HEADER hdr; | ||
261 | u8 Device; | ||
262 | u8 Data[252]; /* followed by two bytes of read data count */ | ||
263 | } __attribute__ ((__packed__)); | ||
264 | |||
265 | struct FW_SPI_WRITE { | ||
266 | struct FW_HEADER hdr; | ||
267 | u8 ModeSelect; | ||
268 | u8 Data[250]; | ||
269 | } __attribute__ ((__packed__)); | ||
270 | |||
271 | struct FW_SPI_READ { | ||
272 | struct FW_HEADER hdr; | ||
273 | u8 ModeSelect; | ||
274 | u8 Data[252]; /* followed by two bytes of read data count */ | ||
275 | } __attribute__ ((__packed__)); | ||
276 | |||
277 | struct FW_FWLOAD_PREPARE { | ||
278 | struct FW_HEADER hdr; | ||
279 | } __attribute__ ((__packed__)); | ||
280 | |||
281 | struct FW_FWLOAD_FINISH { | ||
282 | struct FW_HEADER hdr; | ||
283 | u16 Address; /* address of final block */ | ||
284 | u16 Length; | ||
285 | } __attribute__ ((__packed__)); | ||
286 | |||
287 | /* | ||
288 | * Meaning of FW_STREAM_CONTROL::Mode bits: | ||
289 | * Bit 7: Loopback PEXin to PEXout using TVOut channel | ||
290 | * Bit 6: AVLOOP | ||
291 | * Bit 5: Audio select; 0=I2S, 1=SPDIF | ||
292 | * Bit 4: AVSYNC | ||
293 | * Bit 3: Enable transport stream | ||
294 | * Bit 2: Enable audio capture | ||
295 | * Bit 1: Enable ITU-Video VBI capture | ||
296 | * Bit 0: Enable ITU-Video capture | ||
297 | * | ||
298 | * Meaning of FW_STREAM_CONTROL::Control bits (see UVI1_CTL) | ||
299 | * Bit 7: continuous capture | ||
300 | * Bit 6: capture one field | ||
301 | * Bit 5: capture one frame | ||
302 | * Bit 4: unused | ||
303 | * Bit 3: starting field; 0=odd, 1=even | ||
304 | * Bit 2: sample size; 0=8-bit, 1=10-bit | ||
305 | * Bit 1: data format; 0=UYVY, 1=YUY2 | ||
306 | * Bit 0: resets buffer pointers | ||
307 | */ | ||
308 | |||
309 | enum FSC_MODE_BITS { | ||
310 | SMODE_LOOPBACK = 0x80, | ||
311 | SMODE_AVLOOP = 0x40, | ||
312 | _SMODE_AUDIO_SPDIF = 0x20, | ||
313 | _SMODE_AVSYNC = 0x10, | ||
314 | _SMODE_TRANSPORT_STREAM = 0x08, | ||
315 | _SMODE_AUDIO_CAPTURE = 0x04, | ||
316 | _SMODE_VBI_CAPTURE = 0x02, | ||
317 | _SMODE_VIDEO_CAPTURE = 0x01 | ||
318 | }; | ||
319 | |||
320 | |||
321 | /* Meaning of FW_STREAM_CONTROL::Stream bits: | ||
322 | * Bit 3: Audio sample count: 0 = relative, 1 = absolute | ||
323 | * Bit 2: color bar select; 1=color bars, 0=CV3 decoder | ||
324 | * Bits 1-0: stream select, UVI1, UVI2, TVOUT | ||
325 | */ | ||
326 | |||
327 | struct FW_STREAM_CONTROL { | ||
328 | struct FW_HEADER hdr; | ||
329 | u8 Stream; /* Stream number (UVI1, UVI2, TVOUT) */ | ||
330 | u8 Control; /* Value written to UVI1_CTL */ | ||
331 | u8 Mode; /* Controls clock source */ | ||
332 | u8 SetupDataLen; /* Length of setup data, MSB=1 write | ||
333 | backwards */ | ||
334 | u16 CaptureBlockCount; /* Blocks (a 256 Bytes) to capture per buffer | ||
335 | for TS and Audio */ | ||
336 | u64 Buffer_Address; /* Address of first buffer header */ | ||
337 | u16 BytesPerVideoLine; | ||
338 | u16 MaxLinesPerField; | ||
339 | u16 MinLinesPerField; | ||
340 | u16 Reserved_1; | ||
341 | u16 BytesPerVBILine; | ||
342 | u16 MaxVBILinesPerField; | ||
343 | u16 MinVBILinesPerField; | ||
344 | u16 SetupDataAddr; /* ngene relative address of setup data */ | ||
345 | u8 SetupData[32]; /* setup data */ | ||
346 | } __attribute__((__packed__)); | ||
347 | |||
348 | #define AUDIO_BLOCK_SIZE 256 | ||
349 | #define TS_BLOCK_SIZE 256 | ||
350 | |||
351 | struct FW_MEM_READ { | ||
352 | struct FW_HEADER hdr; | ||
353 | u16 address; | ||
354 | } __attribute__ ((__packed__)); | ||
355 | |||
356 | struct FW_MEM_WRITE { | ||
357 | struct FW_HEADER hdr; | ||
358 | u16 address; | ||
359 | u8 data; | ||
360 | } __attribute__ ((__packed__)); | ||
361 | |||
362 | struct FW_SFR_IRAM_READ { | ||
363 | struct FW_HEADER hdr; | ||
364 | u8 address; | ||
365 | } __attribute__ ((__packed__)); | ||
366 | |||
367 | struct FW_SFR_IRAM_WRITE { | ||
368 | struct FW_HEADER hdr; | ||
369 | u8 address; | ||
370 | u8 data; | ||
371 | } __attribute__ ((__packed__)); | ||
372 | |||
373 | struct FW_SET_GPIO_PIN { | ||
374 | struct FW_HEADER hdr; | ||
375 | u8 select; | ||
376 | } __attribute__ ((__packed__)); | ||
377 | |||
378 | struct FW_SET_GPIO_INT { | ||
379 | struct FW_HEADER hdr; | ||
380 | u8 select; | ||
381 | } __attribute__ ((__packed__)); | ||
382 | |||
383 | struct FW_SET_DEBUGMODE { | ||
384 | struct FW_HEADER hdr; | ||
385 | u8 debug_flags; | ||
386 | } __attribute__ ((__packed__)); | ||
387 | |||
388 | struct FW_CONFIGURE_BUFFERS { | ||
389 | struct FW_HEADER hdr; | ||
390 | u8 config; | ||
391 | } __attribute__ ((__packed__)); | ||
392 | |||
393 | enum _BUFFER_CONFIGS { | ||
394 | /* 4k UVI1, 4k UVI2, 2k AUD1, 2k AUD2 (standard usage) */ | ||
395 | BUFFER_CONFIG_4422 = 0, | ||
396 | /* 3k UVI1, 3k UVI2, 3k AUD1, 3k AUD2 (4x TS input usage) */ | ||
397 | BUFFER_CONFIG_3333 = 1, | ||
398 | /* 8k UVI1, 0k UVI2, 2k AUD1, 2k I2SOut (HDTV decoder usage) */ | ||
399 | BUFFER_CONFIG_8022 = 2, | ||
400 | BUFFER_CONFIG_FW17 = 255, /* Use new FW 17 command */ | ||
401 | }; | ||
402 | |||
403 | struct FW_CONFIGURE_FREE_BUFFERS { | ||
404 | struct FW_HEADER hdr; | ||
405 | u8 UVI1_BufferLength; | ||
406 | u8 UVI2_BufferLength; | ||
407 | u8 TVO_BufferLength; | ||
408 | u8 AUD1_BufferLength; | ||
409 | u8 AUD2_BufferLength; | ||
410 | u8 TVA_BufferLength; | ||
411 | } __attribute__ ((__packed__)); | ||
412 | |||
413 | struct FW_CONFIGURE_UART { | ||
414 | struct FW_HEADER hdr; | ||
415 | u8 UartControl; | ||
416 | } __attribute__ ((__packed__)); | ||
417 | |||
418 | enum _UART_CONFIG { | ||
419 | _UART_BAUDRATE_19200 = 0, | ||
420 | _UART_BAUDRATE_9600 = 1, | ||
421 | _UART_BAUDRATE_4800 = 2, | ||
422 | _UART_BAUDRATE_2400 = 3, | ||
423 | _UART_RX_ENABLE = 0x40, | ||
424 | _UART_TX_ENABLE = 0x80, | ||
425 | }; | ||
426 | |||
427 | struct FW_WRITE_UART { | ||
428 | struct FW_HEADER hdr; | ||
429 | u8 Data[252]; | ||
430 | } __attribute__ ((__packed__)); | ||
431 | |||
432 | |||
433 | struct ngene_command { | ||
434 | u32 in_len; | ||
435 | u32 out_len; | ||
436 | union { | ||
437 | u32 raw[64]; | ||
438 | u8 raw8[256]; | ||
439 | struct FW_HEADER hdr; | ||
440 | struct FW_I2C_WRITE I2CWrite; | ||
441 | struct FW_I2C_CONTINUE_WRITE I2CContinueWrite; | ||
442 | struct FW_I2C_READ I2CRead; | ||
443 | struct FW_STREAM_CONTROL StreamControl; | ||
444 | struct FW_FWLOAD_PREPARE FWLoadPrepare; | ||
445 | struct FW_FWLOAD_FINISH FWLoadFinish; | ||
446 | struct FW_MEM_READ MemoryRead; | ||
447 | struct FW_MEM_WRITE MemoryWrite; | ||
448 | struct FW_SFR_IRAM_READ SfrIramRead; | ||
449 | struct FW_SFR_IRAM_WRITE SfrIramWrite; | ||
450 | struct FW_SPI_WRITE SPIWrite; | ||
451 | struct FW_SPI_READ SPIRead; | ||
452 | struct FW_SET_GPIO_PIN SetGpioPin; | ||
453 | struct FW_SET_GPIO_INT SetGpioInt; | ||
454 | struct FW_SET_DEBUGMODE SetDebugMode; | ||
455 | struct FW_CONFIGURE_BUFFERS ConfigureBuffers; | ||
456 | struct FW_CONFIGURE_FREE_BUFFERS ConfigureFreeBuffers; | ||
457 | struct FW_CONFIGURE_UART ConfigureUart; | ||
458 | struct FW_WRITE_UART WriteUart; | ||
459 | } cmd; | ||
460 | } __attribute__ ((__packed__)); | ||
461 | |||
462 | #define NGENE_INTERFACE_VERSION 0x103 | ||
463 | #define MAX_VIDEO_BUFFER_SIZE (417792) /* 288*1440 rounded up to next page */ | ||
464 | #define MAX_AUDIO_BUFFER_SIZE (8192) /* Gives room for about 23msec@48KHz */ | ||
465 | #define MAX_VBI_BUFFER_SIZE (28672) /* 1144*18 rounded up to next page */ | ||
466 | #define MAX_TS_BUFFER_SIZE (98304) /* 512*188 rounded up to next page */ | ||
467 | #define MAX_HDTV_BUFFER_SIZE (2080768) /* 541*1920*2 rounded up to next page | ||
468 | Max: (1920x1080i60) */ | ||
469 | |||
470 | #define OVERFLOW_BUFFER_SIZE (8192) | ||
471 | |||
472 | #define RING_SIZE_VIDEO 4 | ||
473 | #define RING_SIZE_AUDIO 8 | ||
474 | #define RING_SIZE_TS 8 | ||
475 | |||
476 | #define NUM_SCATTER_GATHER_ENTRIES 8 | ||
477 | |||
478 | #define MAX_DMA_LENGTH (((MAX_VIDEO_BUFFER_SIZE + MAX_VBI_BUFFER_SIZE) * \ | ||
479 | RING_SIZE_VIDEO * 2) + \ | ||
480 | (MAX_AUDIO_BUFFER_SIZE * RING_SIZE_AUDIO * 2) + \ | ||
481 | (MAX_TS_BUFFER_SIZE * RING_SIZE_TS * 4) + \ | ||
482 | (RING_SIZE_VIDEO * PAGE_SIZE * 2) + \ | ||
483 | (RING_SIZE_AUDIO * PAGE_SIZE * 2) + \ | ||
484 | (RING_SIZE_TS * PAGE_SIZE * 4) + \ | ||
485 | 8 * PAGE_SIZE + OVERFLOW_BUFFER_SIZE + PAGE_SIZE) | ||
486 | |||
487 | #define EVENT_QUEUE_SIZE 16 | ||
488 | |||
489 | /* Gathers the current state of a single channel. */ | ||
490 | |||
491 | struct SBufferHeader { | ||
492 | struct BUFFER_HEADER ngeneBuffer; /* Physical descriptor */ | ||
493 | struct SBufferHeader *Next; | ||
494 | void *Buffer1; | ||
495 | struct HW_SCATTER_GATHER_ELEMENT *scList1; | ||
496 | void *Buffer2; | ||
497 | struct HW_SCATTER_GATHER_ELEMENT *scList2; | ||
498 | }; | ||
499 | |||
500 | /* Sizeof SBufferHeader aligned to next 64 Bit boundary (hw restriction) */ | ||
501 | #define SIZEOF_SBufferHeader ((sizeof(struct SBufferHeader) + 63) & ~63) | ||
502 | |||
503 | enum HWSTATE { | ||
504 | HWSTATE_STOP, | ||
505 | HWSTATE_STARTUP, | ||
506 | HWSTATE_RUN, | ||
507 | HWSTATE_PAUSE, | ||
508 | }; | ||
509 | |||
510 | enum KSSTATE { | ||
511 | KSSTATE_STOP, | ||
512 | KSSTATE_ACQUIRE, | ||
513 | KSSTATE_PAUSE, | ||
514 | KSSTATE_RUN, | ||
515 | }; | ||
516 | |||
517 | struct SRingBufferDescriptor { | ||
518 | struct SBufferHeader *Head; /* Points to first buffer in ring buffer | ||
519 | structure*/ | ||
520 | u64 PAHead; /* Physical address of first buffer */ | ||
521 | u32 MemSize; /* Memory size of allocated ring buffers | ||
522 | (needed for freeing) */ | ||
523 | u32 NumBuffers; /* Number of buffers in the ring */ | ||
524 | u32 Buffer1Length; /* Allocated length of Buffer 1 */ | ||
525 | u32 Buffer2Length; /* Allocated length of Buffer 2 */ | ||
526 | void *SCListMem; /* Memory to hold scatter gather lists for this | ||
527 | ring */ | ||
528 | u64 PASCListMem; /* Physical address .. */ | ||
529 | u32 SCListMemSize; /* Size of this memory */ | ||
530 | }; | ||
531 | |||
532 | enum STREAMMODEFLAGS { | ||
533 | StreamMode_NONE = 0, /* Stream not used */ | ||
534 | StreamMode_ANALOG = 1, /* Analog: Stream 0,1 = Video, 2,3 = Audio */ | ||
535 | StreamMode_TSIN = 2, /* Transport stream input (all) */ | ||
536 | StreamMode_HDTV = 4, /* HDTV: Maximum 1920x1080p30,1920x1080i60 | ||
537 | (only stream 0) */ | ||
538 | StreamMode_TSOUT = 8, /* Transport stream output (only stream 3) */ | ||
539 | }; | ||
540 | |||
541 | |||
542 | enum BufferExchangeFlags { | ||
543 | BEF_EVEN_FIELD = 0x00000001, | ||
544 | BEF_CONTINUATION = 0x00000002, | ||
545 | BEF_MORE_DATA = 0x00000004, | ||
546 | BEF_OVERFLOW = 0x00000008, | ||
547 | DF_SWAP32 = 0x00010000, | ||
548 | }; | ||
549 | |||
550 | typedef void *(IBufferExchange)(void *, void *, u32, u32, u32); | ||
551 | |||
552 | struct MICI_STREAMINFO { | ||
553 | IBufferExchange *pExchange; | ||
554 | IBufferExchange *pExchangeVBI; /* Secondary (VBI, ancillary) */ | ||
555 | u8 Stream; | ||
556 | u8 Flags; | ||
557 | u8 Mode; | ||
558 | u8 Reserved; | ||
559 | u16 nLinesVideo; | ||
560 | u16 nBytesPerLineVideo; | ||
561 | u16 nLinesVBI; | ||
562 | u16 nBytesPerLineVBI; | ||
563 | u32 CaptureLength; /* Used for audio and transport stream */ | ||
564 | }; | ||
565 | |||
566 | /****************************************************************************/ | ||
567 | /* STRUCTS ******************************************************************/ | ||
568 | /****************************************************************************/ | ||
569 | |||
570 | /* sound hardware definition */ | ||
571 | #define MIXER_ADDR_TVTUNER 0 | ||
572 | #define MIXER_ADDR_LAST 0 | ||
573 | |||
574 | struct ngene_channel; | ||
575 | |||
576 | /*struct sound chip*/ | ||
577 | |||
578 | struct mychip { | ||
579 | struct ngene_channel *chan; | ||
580 | struct snd_card *card; | ||
581 | struct pci_dev *pci; | ||
582 | struct snd_pcm_substream *substream; | ||
583 | struct snd_pcm *pcm; | ||
584 | unsigned long port; | ||
585 | int irq; | ||
586 | spinlock_t mixer_lock; | ||
587 | spinlock_t lock; | ||
588 | int mixer_volume[MIXER_ADDR_LAST + 1][2]; | ||
589 | int capture_source[MIXER_ADDR_LAST + 1][2]; | ||
590 | }; | ||
591 | |||
592 | #ifdef NGENE_V4L | ||
593 | struct ngene_overlay { | ||
594 | int tvnorm; | ||
595 | struct v4l2_rect w; | ||
596 | enum v4l2_field field; | ||
597 | struct v4l2_clip *clips; | ||
598 | int nclips; | ||
599 | int setup_ok; | ||
600 | }; | ||
601 | |||
602 | struct ngene_tvnorm { | ||
603 | int v4l2_id; | ||
604 | char *name; | ||
605 | u16 swidth, sheight; /* scaled standard width, height */ | ||
606 | int tuner_norm; | ||
607 | int soundstd; | ||
608 | }; | ||
609 | |||
610 | struct ngene_vopen { | ||
611 | struct ngene_channel *ch; | ||
612 | enum v4l2_priority prio; | ||
613 | int width; | ||
614 | int height; | ||
615 | int depth; | ||
616 | struct videobuf_queue vbuf_q; | ||
617 | struct videobuf_queue vbi; | ||
618 | int fourcc; | ||
619 | int picxcount; | ||
620 | int resources; | ||
621 | enum v4l2_buf_type type; | ||
622 | const struct ngene_format *fmt; | ||
623 | |||
624 | const struct ngene_format *ovfmt; | ||
625 | struct ngene_overlay ov; | ||
626 | }; | ||
627 | #endif | ||
628 | |||
629 | struct ngene_channel { | ||
630 | struct device device; | ||
631 | struct i2c_adapter i2c_adapter; | ||
632 | |||
633 | struct ngene *dev; | ||
634 | int number; | ||
635 | int type; | ||
636 | int mode; | ||
637 | |||
638 | struct dvb_frontend *fe; | ||
639 | struct dmxdev dmxdev; | ||
640 | struct dvb_demux demux; | ||
641 | struct dmx_frontend hw_frontend; | ||
642 | struct dmx_frontend mem_frontend; | ||
643 | int users; | ||
644 | struct video_device *v4l_dev; | ||
645 | struct tasklet_struct demux_tasklet; | ||
646 | |||
647 | struct SBufferHeader *nextBuffer; | ||
648 | enum KSSTATE State; | ||
649 | enum HWSTATE HWState; | ||
650 | u8 Stream; | ||
651 | u8 Flags; | ||
652 | u8 Mode; | ||
653 | IBufferExchange *pBufferExchange; | ||
654 | IBufferExchange *pBufferExchange2; | ||
655 | |||
656 | spinlock_t state_lock; | ||
657 | u16 nLines; | ||
658 | u16 nBytesPerLine; | ||
659 | u16 nVBILines; | ||
660 | u16 nBytesPerVBILine; | ||
661 | u16 itumode; | ||
662 | u32 Capture1Length; | ||
663 | u32 Capture2Length; | ||
664 | struct SRingBufferDescriptor RingBuffer; | ||
665 | struct SRingBufferDescriptor TSRingBuffer; | ||
666 | struct SRingBufferDescriptor TSIdleBuffer; | ||
667 | |||
668 | u32 DataFormatFlags; | ||
669 | |||
670 | int AudioDTOUpdated; | ||
671 | u32 AudioDTOValue; | ||
672 | |||
673 | int (*set_tone)(struct dvb_frontend *, fe_sec_tone_mode_t); | ||
674 | u8 lnbh; | ||
675 | |||
676 | /* stuff from analog driver */ | ||
677 | |||
678 | int minor; | ||
679 | struct mychip *mychip; | ||
680 | struct snd_card *soundcard; | ||
681 | u8 *evenbuffer; | ||
682 | u8 dma_on; | ||
683 | int soundstreamon; | ||
684 | int audiomute; | ||
685 | int soundbuffisallocated; | ||
686 | int sndbuffflag; | ||
687 | int tun_rdy; | ||
688 | int dec_rdy; | ||
689 | int tun_dec_rdy; | ||
690 | int lastbufferflag; | ||
691 | |||
692 | struct ngene_tvnorm *tvnorms; | ||
693 | int tvnorm_num; | ||
694 | int tvnorm; | ||
695 | |||
696 | #ifdef NGENE_V4L | ||
697 | int videousers; | ||
698 | struct v4l2_prio_state prio; | ||
699 | struct ngene_vopen init; | ||
700 | int resources; | ||
701 | struct v4l2_framebuffer fbuf; | ||
702 | struct ngene_buffer *screen; /* overlay */ | ||
703 | struct list_head capture; /* video capture queue */ | ||
704 | spinlock_t s_lock; | ||
705 | struct semaphore reslock; | ||
706 | #endif | ||
707 | |||
708 | int running; | ||
709 | }; | ||
710 | |||
711 | struct ngene; | ||
712 | |||
713 | typedef void (rx_cb_t)(struct ngene *, u32, u8); | ||
714 | typedef void (tx_cb_t)(struct ngene *, u32); | ||
715 | |||
716 | struct ngene { | ||
717 | int nr; | ||
718 | struct pci_dev *pci_dev; | ||
719 | unsigned char *iomem; | ||
720 | |||
721 | /*struct i2c_adapter i2c_adapter;*/ | ||
722 | |||
723 | u32 device_version; | ||
724 | u32 fw_interface_version; | ||
725 | u32 icounts; | ||
726 | |||
727 | u8 *CmdDoneByte; | ||
728 | int BootFirmware; | ||
729 | void *OverflowBuffer; | ||
730 | dma_addr_t PAOverflowBuffer; | ||
731 | void *FWInterfaceBuffer; | ||
732 | dma_addr_t PAFWInterfaceBuffer; | ||
733 | u8 *ngenetohost; | ||
734 | u8 *hosttongene; | ||
735 | |||
736 | struct EVENT_BUFFER EventQueue[EVENT_QUEUE_SIZE]; | ||
737 | int EventQueueOverflowCount; | ||
738 | int EventQueueOverflowFlag; | ||
739 | struct tasklet_struct event_tasklet; | ||
740 | struct EVENT_BUFFER *EventBuffer; | ||
741 | int EventQueueWriteIndex; | ||
742 | int EventQueueReadIndex; | ||
743 | |||
744 | wait_queue_head_t cmd_wq; | ||
745 | int cmd_done; | ||
746 | struct semaphore cmd_mutex; | ||
747 | struct semaphore stream_mutex; | ||
748 | struct semaphore pll_mutex; | ||
749 | struct semaphore i2c_switch_mutex; | ||
750 | int i2c_current_channel; | ||
751 | int i2c_current_bus; | ||
752 | spinlock_t cmd_lock; | ||
753 | |||
754 | struct dvb_adapter adapter[MAX_STREAM]; | ||
755 | struct ngene_channel channel[MAX_STREAM]; | ||
756 | |||
757 | struct ngene_info *card_info; | ||
758 | |||
759 | tx_cb_t *TxEventNotify; | ||
760 | rx_cb_t *RxEventNotify; | ||
761 | int tx_busy; | ||
762 | wait_queue_head_t tx_wq; | ||
763 | wait_queue_head_t rx_wq; | ||
764 | #define UART_RBUF_LEN 4096 | ||
765 | u8 uart_rbuf[UART_RBUF_LEN]; | ||
766 | int uart_rp, uart_wp; | ||
767 | |||
768 | u8 *tsout_buf; | ||
769 | #define TSOUT_BUF_SIZE (512*188*8) | ||
770 | struct dvb_ringbuffer tsout_rbuf; | ||
771 | |||
772 | u8 *ain_buf; | ||
773 | #define AIN_BUF_SIZE (128*1024) | ||
774 | struct dvb_ringbuffer ain_rbuf; | ||
775 | |||
776 | |||
777 | u8 *vin_buf; | ||
778 | #define VIN_BUF_SIZE (4*1920*1080) | ||
779 | struct dvb_ringbuffer vin_rbuf; | ||
780 | |||
781 | unsigned long exp_val; | ||
782 | int prev_cmd; | ||
783 | }; | ||
784 | |||
785 | struct ngene_info { | ||
786 | int type; | ||
787 | #define NGENE_APP 0 | ||
788 | #define NGENE_TERRATEC 1 | ||
789 | #define NGENE_SIDEWINDER 2 | ||
790 | #define NGENE_RACER 3 | ||
791 | #define NGENE_VIPER 4 | ||
792 | #define NGENE_PYTHON 5 | ||
793 | #define NGENE_VBOX_V1 6 | ||
794 | #define NGENE_VBOX_V2 7 | ||
795 | |||
796 | int fw_version; | ||
797 | char *name; | ||
798 | |||
799 | int io_type[MAX_STREAM]; | ||
800 | #define NGENE_IO_NONE 0 | ||
801 | #define NGENE_IO_TV 1 | ||
802 | #define NGENE_IO_HDTV 2 | ||
803 | #define NGENE_IO_TSIN 4 | ||
804 | #define NGENE_IO_TSOUT 8 | ||
805 | #define NGENE_IO_AIN 16 | ||
806 | |||
807 | void *fe_config[4]; | ||
808 | void *tuner_config[4]; | ||
809 | |||
810 | int (*demod_attach[4])(struct ngene_channel *); | ||
811 | int (*tuner_attach[4])(struct ngene_channel *); | ||
812 | |||
813 | u8 avf[4]; | ||
814 | u8 msp[4]; | ||
815 | u8 demoda[4]; | ||
816 | u8 lnb[4]; | ||
817 | int i2c_access; | ||
818 | u8 ntsc; | ||
819 | u8 tsf[4]; | ||
820 | u8 i2s[4]; | ||
821 | |||
822 | int (*gate_ctrl)(struct dvb_frontend *, int); | ||
823 | int (*switch_ctrl)(struct ngene_channel *, int, int); | ||
824 | }; | ||
825 | |||
826 | #ifdef NGENE_V4L | ||
827 | struct ngene_format{ | ||
828 | char *name; | ||
829 | int fourcc; /* video4linux 2 */ | ||
830 | int btformat; /* BT848_COLOR_FMT_* */ | ||
831 | int format; | ||
832 | int btswap; /* BT848_COLOR_CTL_* */ | ||
833 | int depth; /* bit/pixel */ | ||
834 | int flags; | ||
835 | int hshift, vshift; /* for planar modes */ | ||
836 | int palette; | ||
837 | }; | ||
838 | |||
839 | #define RESOURCE_OVERLAY 1 | ||
840 | #define RESOURCE_VIDEO 2 | ||
841 | #define RESOURCE_VBI 4 | ||
842 | |||
843 | struct ngene_buffer { | ||
844 | /* common v4l buffer stuff -- must be first */ | ||
845 | struct videobuf_buffer vb; | ||
846 | |||
847 | /* ngene specific */ | ||
848 | const struct ngene_format *fmt; | ||
849 | int tvnorm; | ||
850 | int btformat; | ||
851 | int btswap; | ||
852 | }; | ||
853 | #endif | ||
854 | |||
855 | |||
856 | #endif | ||
857 | |||
858 | /* LocalWords: Endif | ||
859 | */ | ||
diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c index 1067b22eb0c6..cff77e2eb557 100644 --- a/drivers/media/dvb/siano/sms-cards.c +++ b/drivers/media/dvb/siano/sms-cards.c | |||
@@ -62,6 +62,7 @@ static struct sms_board sms_boards[] = { | |||
62 | [SMS1XXX_BOARD_HAUPPAUGE_WINDHAM] = { | 62 | [SMS1XXX_BOARD_HAUPPAUGE_WINDHAM] = { |
63 | .name = "Hauppauge WinTV MiniStick", | 63 | .name = "Hauppauge WinTV MiniStick", |
64 | .type = SMS_NOVA_B0, | 64 | .type = SMS_NOVA_B0, |
65 | .fw[DEVICE_MODE_ISDBT_BDA] = "sms1xxx-hcw-55xxx-isdbt-02.fw", | ||
65 | .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", | 66 | .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", |
66 | .board_cfg.leds_power = 26, | 67 | .board_cfg.leds_power = 26, |
67 | .board_cfg.led0 = 27, | 68 | .board_cfg.led0 = 27, |
diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index ca758bcb48c9..4bfd3451b568 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c | |||
@@ -1459,8 +1459,10 @@ int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum, | |||
1459 | if (!(coredev->device_flags & SMS_DEVICE_FAMILY2)) { | 1459 | if (!(coredev->device_flags & SMS_DEVICE_FAMILY2)) { |
1460 | pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_REQ; | 1460 | pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_REQ; |
1461 | if (GetGpioPinParams(PinNum, &TranslatedPinNum, &GroupNum, | 1461 | if (GetGpioPinParams(PinNum, &TranslatedPinNum, &GroupNum, |
1462 | &groupCfg) != 0) | 1462 | &groupCfg) != 0) { |
1463 | return -EINVAL; | 1463 | rc = -EINVAL; |
1464 | goto free; | ||
1465 | } | ||
1464 | 1466 | ||
1465 | pMsg->msgData[1] = TranslatedPinNum; | 1467 | pMsg->msgData[1] = TranslatedPinNum; |
1466 | pMsg->msgData[2] = GroupNum; | 1468 | pMsg->msgData[2] = GroupNum; |
@@ -1490,6 +1492,7 @@ int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum, | |||
1490 | else | 1492 | else |
1491 | sms_err("smscore_gpio_configure error"); | 1493 | sms_err("smscore_gpio_configure error"); |
1492 | } | 1494 | } |
1495 | free: | ||
1493 | kfree(buffer); | 1496 | kfree(buffer); |
1494 | 1497 | ||
1495 | return rc; | 1498 | return rc; |
diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h index eec18aaf5512..8ecadecaa9d0 100644 --- a/drivers/media/dvb/siano/smscoreapi.h +++ b/drivers/media/dvb/siano/smscoreapi.h | |||
@@ -212,6 +212,8 @@ struct smscore_device_t { | |||
212 | #define MSG_SMS_DAB_CHANNEL 607 | 212 | #define MSG_SMS_DAB_CHANNEL 607 |
213 | #define MSG_SMS_GET_PID_FILTER_LIST_REQ 608 | 213 | #define MSG_SMS_GET_PID_FILTER_LIST_REQ 608 |
214 | #define MSG_SMS_GET_PID_FILTER_LIST_RES 609 | 214 | #define MSG_SMS_GET_PID_FILTER_LIST_RES 609 |
215 | #define MSG_SMS_GET_STATISTICS_RES 616 | ||
216 | #define MSG_SMS_GET_STATISTICS_REQ 615 | ||
215 | #define MSG_SMS_HO_PER_SLICES_IND 630 | 217 | #define MSG_SMS_HO_PER_SLICES_IND 630 |
216 | #define MSG_SMS_SET_ANTENNA_CONFIG_REQ 651 | 218 | #define MSG_SMS_SET_ANTENNA_CONFIG_REQ 651 |
217 | #define MSG_SMS_SET_ANTENNA_CONFIG_RES 652 | 219 | #define MSG_SMS_SET_ANTENNA_CONFIG_RES 652 |
@@ -339,7 +341,7 @@ struct SmsFirmware_ST { | |||
339 | 341 | ||
340 | /* Statistics information returned as response for | 342 | /* Statistics information returned as response for |
341 | * SmsHostApiGetStatistics_Req */ | 343 | * SmsHostApiGetStatistics_Req */ |
342 | struct SMSHOSTLIB_STATISTICS_S { | 344 | struct SMSHOSTLIB_STATISTICS_ST { |
343 | u32 Reserved; /* Reserved */ | 345 | u32 Reserved; /* Reserved */ |
344 | 346 | ||
345 | /* Common parameters */ | 347 | /* Common parameters */ |
@@ -424,6 +426,79 @@ struct SMSHOSTLIB_STATISTICS_S { | |||
424 | u32 ReservedFields[10]; /* Reserved */ | 426 | u32 ReservedFields[10]; /* Reserved */ |
425 | }; | 427 | }; |
426 | 428 | ||
429 | struct SmsMsgStatisticsInfo_ST { | ||
430 | u32 RequestResult; | ||
431 | |||
432 | struct SMSHOSTLIB_STATISTICS_ST Stat; | ||
433 | |||
434 | /* Split the calc of the SNR in DAB */ | ||
435 | u32 Signal; /* dB */ | ||
436 | u32 Noise; /* dB */ | ||
437 | |||
438 | }; | ||
439 | |||
440 | struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST { | ||
441 | /* Per-layer information */ | ||
442 | u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET, | ||
443 | * 255 means layer does not exist */ | ||
444 | u32 Constellation; /* Constellation from SMSHOSTLIB_CONSTELLATION_ET, | ||
445 | * 255 means layer does not exist */ | ||
446 | u32 BER; /* Post Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */ | ||
447 | u32 BERErrorCount; /* Post Viterbi Error Bits Count */ | ||
448 | u32 BERBitCount; /* Post Viterbi Total Bits Count */ | ||
449 | u32 PreBER; /* Pre Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */ | ||
450 | u32 TS_PER; /* Transport stream PER [%], 0xFFFFFFFF indicate N/A */ | ||
451 | u32 ErrorTSPackets; /* Number of erroneous transport-stream packets */ | ||
452 | u32 TotalTSPackets; /* Total number of transport-stream packets */ | ||
453 | u32 TILdepthI; /* Time interleaver depth I parameter, | ||
454 | * 255 means layer does not exist */ | ||
455 | u32 NumberOfSegments; /* Number of segments in layer A, | ||
456 | * 255 means layer does not exist */ | ||
457 | u32 TMCCErrors; /* TMCC errors */ | ||
458 | }; | ||
459 | |||
460 | struct SMSHOSTLIB_STATISTICS_ISDBT_ST { | ||
461 | u32 StatisticsType; /* Enumerator identifying the type of the | ||
462 | * structure. Values are the same as | ||
463 | * SMSHOSTLIB_DEVICE_MODES_E | ||
464 | * | ||
465 | * This field MUST always be first in any | ||
466 | * statistics structure */ | ||
467 | |||
468 | u32 FullSize; /* Total size of the structure returned by the modem. | ||
469 | * If the size requested by the host is smaller than | ||
470 | * FullSize, the struct will be truncated */ | ||
471 | |||
472 | /* Common parameters */ | ||
473 | u32 IsRfLocked; /* 0 - not locked, 1 - locked */ | ||
474 | u32 IsDemodLocked; /* 0 - not locked, 1 - locked */ | ||
475 | u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */ | ||
476 | |||
477 | /* Reception quality */ | ||
478 | s32 SNR; /* dB */ | ||
479 | s32 RSSI; /* dBm */ | ||
480 | s32 InBandPwr; /* In band power in dBM */ | ||
481 | s32 CarrierOffset; /* Carrier Offset in Hz */ | ||
482 | |||
483 | /* Transmission parameters */ | ||
484 | u32 Frequency; /* Frequency in Hz */ | ||
485 | u32 Bandwidth; /* Bandwidth in MHz */ | ||
486 | u32 TransmissionMode; /* ISDB-T transmission mode */ | ||
487 | u32 ModemState; /* 0 - Acquisition, 1 - Locked */ | ||
488 | u32 GuardInterval; /* Guard Interval, 1 divided by value */ | ||
489 | u32 SystemType; /* ISDB-T system type (ISDB-T / ISDB-Tsb) */ | ||
490 | u32 PartialReception; /* TRUE - partial reception, FALSE otherwise */ | ||
491 | u32 NumOfLayers; /* Number of ISDB-T layers in the network */ | ||
492 | |||
493 | /* Per-layer information */ | ||
494 | /* Layers A, B and C */ | ||
495 | struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST LayerInfo[3]; | ||
496 | /* Per-layer statistics, see SMSHOSTLIB_ISDBT_LAYER_STAT_ST */ | ||
497 | |||
498 | /* Interface information */ | ||
499 | u32 SmsToHostTxErrors; /* Total number of transmission errors. */ | ||
500 | }; | ||
501 | |||
427 | struct PID_STATISTICS_DATA_S { | 502 | struct PID_STATISTICS_DATA_S { |
428 | struct PID_BURST_S { | 503 | struct PID_BURST_S { |
429 | u32 size; | 504 | u32 size; |
diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c index 68bf9fbd8fed..5f3939821ca3 100644 --- a/drivers/media/dvb/siano/smsdvb.c +++ b/drivers/media/dvb/siano/smsdvb.c | |||
@@ -116,6 +116,118 @@ static void sms_board_dvb3_event(struct smsdvb_client_t *client, | |||
116 | } | 116 | } |
117 | } | 117 | } |
118 | 118 | ||
119 | |||
120 | static void smsdvb_update_dvb_stats(struct RECEPTION_STATISTICS_S *pReceptionData, | ||
121 | struct SMSHOSTLIB_STATISTICS_ST *p) | ||
122 | { | ||
123 | if (sms_dbg & 2) { | ||
124 | printk(KERN_DEBUG "Reserved = %d", p->Reserved); | ||
125 | printk(KERN_DEBUG "IsRfLocked = %d", p->IsRfLocked); | ||
126 | printk(KERN_DEBUG "IsDemodLocked = %d", p->IsDemodLocked); | ||
127 | printk(KERN_DEBUG "IsExternalLNAOn = %d", p->IsExternalLNAOn); | ||
128 | printk(KERN_DEBUG "SNR = %d", p->SNR); | ||
129 | printk(KERN_DEBUG "BER = %d", p->BER); | ||
130 | printk(KERN_DEBUG "FIB_CRC = %d", p->FIB_CRC); | ||
131 | printk(KERN_DEBUG "TS_PER = %d", p->TS_PER); | ||
132 | printk(KERN_DEBUG "MFER = %d", p->MFER); | ||
133 | printk(KERN_DEBUG "RSSI = %d", p->RSSI); | ||
134 | printk(KERN_DEBUG "InBandPwr = %d", p->InBandPwr); | ||
135 | printk(KERN_DEBUG "CarrierOffset = %d", p->CarrierOffset); | ||
136 | printk(KERN_DEBUG "Frequency = %d", p->Frequency); | ||
137 | printk(KERN_DEBUG "Bandwidth = %d", p->Bandwidth); | ||
138 | printk(KERN_DEBUG "TransmissionMode = %d", p->TransmissionMode); | ||
139 | printk(KERN_DEBUG "ModemState = %d", p->ModemState); | ||
140 | printk(KERN_DEBUG "GuardInterval = %d", p->GuardInterval); | ||
141 | printk(KERN_DEBUG "CodeRate = %d", p->CodeRate); | ||
142 | printk(KERN_DEBUG "LPCodeRate = %d", p->LPCodeRate); | ||
143 | printk(KERN_DEBUG "Hierarchy = %d", p->Hierarchy); | ||
144 | printk(KERN_DEBUG "Constellation = %d", p->Constellation); | ||
145 | printk(KERN_DEBUG "BurstSize = %d", p->BurstSize); | ||
146 | printk(KERN_DEBUG "BurstDuration = %d", p->BurstDuration); | ||
147 | printk(KERN_DEBUG "BurstCycleTime = %d", p->BurstCycleTime); | ||
148 | printk(KERN_DEBUG "CalculatedBurstCycleTime = %d", p->CalculatedBurstCycleTime); | ||
149 | printk(KERN_DEBUG "NumOfRows = %d", p->NumOfRows); | ||
150 | printk(KERN_DEBUG "NumOfPaddCols = %d", p->NumOfPaddCols); | ||
151 | printk(KERN_DEBUG "NumOfPunctCols = %d", p->NumOfPunctCols); | ||
152 | printk(KERN_DEBUG "ErrorTSPackets = %d", p->ErrorTSPackets); | ||
153 | printk(KERN_DEBUG "TotalTSPackets = %d", p->TotalTSPackets); | ||
154 | printk(KERN_DEBUG "NumOfValidMpeTlbs = %d", p->NumOfValidMpeTlbs); | ||
155 | printk(KERN_DEBUG "NumOfInvalidMpeTlbs = %d", p->NumOfInvalidMpeTlbs); | ||
156 | printk(KERN_DEBUG "NumOfCorrectedMpeTlbs = %d", p->NumOfCorrectedMpeTlbs); | ||
157 | printk(KERN_DEBUG "BERErrorCount = %d", p->BERErrorCount); | ||
158 | printk(KERN_DEBUG "BERBitCount = %d", p->BERBitCount); | ||
159 | printk(KERN_DEBUG "SmsToHostTxErrors = %d", p->SmsToHostTxErrors); | ||
160 | printk(KERN_DEBUG "PreBER = %d", p->PreBER); | ||
161 | printk(KERN_DEBUG "CellId = %d", p->CellId); | ||
162 | printk(KERN_DEBUG "DvbhSrvIndHP = %d", p->DvbhSrvIndHP); | ||
163 | printk(KERN_DEBUG "DvbhSrvIndLP = %d", p->DvbhSrvIndLP); | ||
164 | printk(KERN_DEBUG "NumMPEReceived = %d", p->NumMPEReceived); | ||
165 | } | ||
166 | |||
167 | pReceptionData->IsDemodLocked = p->IsDemodLocked; | ||
168 | |||
169 | pReceptionData->SNR = p->SNR; | ||
170 | pReceptionData->BER = p->BER; | ||
171 | pReceptionData->BERErrorCount = p->BERErrorCount; | ||
172 | pReceptionData->InBandPwr = p->InBandPwr; | ||
173 | pReceptionData->ErrorTSPackets = p->ErrorTSPackets; | ||
174 | }; | ||
175 | |||
176 | |||
177 | static void smsdvb_update_isdbt_stats(struct RECEPTION_STATISTICS_S *pReceptionData, | ||
178 | struct SMSHOSTLIB_STATISTICS_ISDBT_ST *p) | ||
179 | { | ||
180 | int i; | ||
181 | |||
182 | if (sms_dbg & 2) { | ||
183 | printk(KERN_DEBUG "IsRfLocked = %d", p->IsRfLocked); | ||
184 | printk(KERN_DEBUG "IsDemodLocked = %d", p->IsDemodLocked); | ||
185 | printk(KERN_DEBUG "IsExternalLNAOn = %d", p->IsExternalLNAOn); | ||
186 | printk(KERN_DEBUG "SNR = %d", p->SNR); | ||
187 | printk(KERN_DEBUG "RSSI = %d", p->RSSI); | ||
188 | printk(KERN_DEBUG "InBandPwr = %d", p->InBandPwr); | ||
189 | printk(KERN_DEBUG "CarrierOffset = %d", p->CarrierOffset); | ||
190 | printk(KERN_DEBUG "Frequency = %d", p->Frequency); | ||
191 | printk(KERN_DEBUG "Bandwidth = %d", p->Bandwidth); | ||
192 | printk(KERN_DEBUG "TransmissionMode = %d", p->TransmissionMode); | ||
193 | printk(KERN_DEBUG "ModemState = %d", p->ModemState); | ||
194 | printk(KERN_DEBUG "GuardInterval = %d", p->GuardInterval); | ||
195 | printk(KERN_DEBUG "SystemType = %d", p->SystemType); | ||
196 | printk(KERN_DEBUG "PartialReception = %d", p->PartialReception); | ||
197 | printk(KERN_DEBUG "NumOfLayers = %d", p->NumOfLayers); | ||
198 | printk(KERN_DEBUG "SmsToHostTxErrors = %d", p->SmsToHostTxErrors); | ||
199 | |||
200 | for (i = 0; i < 3; i++) { | ||
201 | printk(KERN_DEBUG "%d: CodeRate = %d", i, p->LayerInfo[i].CodeRate); | ||
202 | printk(KERN_DEBUG "%d: Constellation = %d", i, p->LayerInfo[i].Constellation); | ||
203 | printk(KERN_DEBUG "%d: BER = %d", i, p->LayerInfo[i].BER); | ||
204 | printk(KERN_DEBUG "%d: BERErrorCount = %d", i, p->LayerInfo[i].BERErrorCount); | ||
205 | printk(KERN_DEBUG "%d: BERBitCount = %d", i, p->LayerInfo[i].BERBitCount); | ||
206 | printk(KERN_DEBUG "%d: PreBER = %d", i, p->LayerInfo[i].PreBER); | ||
207 | printk(KERN_DEBUG "%d: TS_PER = %d", i, p->LayerInfo[i].TS_PER); | ||
208 | printk(KERN_DEBUG "%d: ErrorTSPackets = %d", i, p->LayerInfo[i].ErrorTSPackets); | ||
209 | printk(KERN_DEBUG "%d: TotalTSPackets = %d", i, p->LayerInfo[i].TotalTSPackets); | ||
210 | printk(KERN_DEBUG "%d: TILdepthI = %d", i, p->LayerInfo[i].TILdepthI); | ||
211 | printk(KERN_DEBUG "%d: NumberOfSegments = %d", i, p->LayerInfo[i].NumberOfSegments); | ||
212 | printk(KERN_DEBUG "%d: TMCCErrors = %d", i, p->LayerInfo[i].TMCCErrors); | ||
213 | } | ||
214 | } | ||
215 | |||
216 | pReceptionData->IsDemodLocked = p->IsDemodLocked; | ||
217 | |||
218 | pReceptionData->SNR = p->SNR; | ||
219 | pReceptionData->InBandPwr = p->InBandPwr; | ||
220 | |||
221 | pReceptionData->ErrorTSPackets = 0; | ||
222 | pReceptionData->BER = 0; | ||
223 | pReceptionData->BERErrorCount = 0; | ||
224 | for (i = 0; i < 3; i++) { | ||
225 | pReceptionData->BER += p->LayerInfo[i].BER; | ||
226 | pReceptionData->BERErrorCount += p->LayerInfo[i].BERErrorCount; | ||
227 | pReceptionData->ErrorTSPackets += p->LayerInfo[i].ErrorTSPackets; | ||
228 | } | ||
229 | } | ||
230 | |||
119 | static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) | 231 | static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) |
120 | { | 232 | { |
121 | struct smsdvb_client_t *client = (struct smsdvb_client_t *) context; | 233 | struct smsdvb_client_t *client = (struct smsdvb_client_t *) context; |
@@ -134,6 +246,7 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) | |||
134 | break; | 246 | break; |
135 | 247 | ||
136 | case MSG_SMS_RF_TUNE_RES: | 248 | case MSG_SMS_RF_TUNE_RES: |
249 | case MSG_SMS_ISDBT_TUNE_RES: | ||
137 | complete(&client->tune_done); | 250 | complete(&client->tune_done); |
138 | break; | 251 | break; |
139 | 252 | ||
@@ -217,6 +330,40 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) | |||
217 | is_status_update = true; | 330 | is_status_update = true; |
218 | break; | 331 | break; |
219 | } | 332 | } |
333 | case MSG_SMS_GET_STATISTICS_RES: { | ||
334 | union { | ||
335 | struct SMSHOSTLIB_STATISTICS_ISDBT_ST isdbt; | ||
336 | struct SmsMsgStatisticsInfo_ST dvb; | ||
337 | } *p = (void *) (phdr + 1); | ||
338 | struct RECEPTION_STATISTICS_S *pReceptionData = | ||
339 | &client->sms_stat_dvb.ReceptionData; | ||
340 | |||
341 | sms_info("MSG_SMS_GET_STATISTICS_RES"); | ||
342 | |||
343 | is_status_update = true; | ||
344 | |||
345 | switch (smscore_get_device_mode(client->coredev)) { | ||
346 | case DEVICE_MODE_ISDBT: | ||
347 | case DEVICE_MODE_ISDBT_BDA: | ||
348 | smsdvb_update_isdbt_stats(pReceptionData, &p->isdbt); | ||
349 | break; | ||
350 | default: | ||
351 | smsdvb_update_dvb_stats(pReceptionData, &p->dvb.Stat); | ||
352 | } | ||
353 | if (!pReceptionData->IsDemodLocked) { | ||
354 | pReceptionData->SNR = 0; | ||
355 | pReceptionData->BER = 0; | ||
356 | pReceptionData->BERErrorCount = 0; | ||
357 | pReceptionData->InBandPwr = 0; | ||
358 | pReceptionData->ErrorTSPackets = 0; | ||
359 | } | ||
360 | |||
361 | complete(&client->tune_done); | ||
362 | break; | ||
363 | } | ||
364 | default: | ||
365 | sms_info("Unhandled message %d", phdr->msgType); | ||
366 | |||
220 | } | 367 | } |
221 | smscore_putbuffer(client->coredev, cb); | 368 | smscore_putbuffer(client->coredev, cb); |
222 | 369 | ||
@@ -233,10 +380,10 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) | |||
233 | DVB3_EVENT_UNC_ERR); | 380 | DVB3_EVENT_UNC_ERR); |
234 | 381 | ||
235 | } else { | 382 | } else { |
236 | /*client->fe_status = | 383 | if (client->sms_stat_dvb.ReceptionData.IsRfLocked) |
237 | (phdr->msgType == MSG_SMS_NO_SIGNAL_IND) ? | 384 | client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER; |
238 | 0 : FE_HAS_SIGNAL;*/ | 385 | else |
239 | client->fe_status = 0; | 386 | client->fe_status = 0; |
240 | sms_board_dvb3_event(client, DVB3_EVENT_FE_UNLOCK); | 387 | sms_board_dvb3_event(client, DVB3_EVENT_FE_UNLOCK); |
241 | } | 388 | } |
242 | } | 389 | } |
@@ -325,6 +472,20 @@ static int smsdvb_sendrequest_and_wait(struct smsdvb_client_t *client, | |||
325 | 0 : -ETIME; | 472 | 0 : -ETIME; |
326 | } | 473 | } |
327 | 474 | ||
475 | static int smsdvb_send_statistics_request(struct smsdvb_client_t *client) | ||
476 | { | ||
477 | int rc; | ||
478 | struct SmsMsgHdr_ST Msg = { MSG_SMS_GET_STATISTICS_REQ, | ||
479 | DVBT_BDA_CONTROL_MSG_ID, | ||
480 | HIF_TASK, | ||
481 | sizeof(struct SmsMsgHdr_ST), 0 }; | ||
482 | |||
483 | rc = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), | ||
484 | &client->tune_done); | ||
485 | |||
486 | return rc; | ||
487 | } | ||
488 | |||
328 | static inline int led_feedback(struct smsdvb_client_t *client) | 489 | static inline int led_feedback(struct smsdvb_client_t *client) |
329 | { | 490 | { |
330 | if (client->fe_status & FE_HAS_LOCK) | 491 | if (client->fe_status & FE_HAS_LOCK) |
@@ -337,33 +498,43 @@ static inline int led_feedback(struct smsdvb_client_t *client) | |||
337 | 498 | ||
338 | static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat) | 499 | static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat) |
339 | { | 500 | { |
501 | int rc; | ||
340 | struct smsdvb_client_t *client; | 502 | struct smsdvb_client_t *client; |
341 | client = container_of(fe, struct smsdvb_client_t, frontend); | 503 | client = container_of(fe, struct smsdvb_client_t, frontend); |
342 | 504 | ||
505 | rc = smsdvb_send_statistics_request(client); | ||
506 | |||
343 | *stat = client->fe_status; | 507 | *stat = client->fe_status; |
344 | 508 | ||
345 | led_feedback(client); | 509 | led_feedback(client); |
346 | 510 | ||
347 | return 0; | 511 | return rc; |
348 | } | 512 | } |
349 | 513 | ||
350 | static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber) | 514 | static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber) |
351 | { | 515 | { |
516 | int rc; | ||
352 | struct smsdvb_client_t *client; | 517 | struct smsdvb_client_t *client; |
353 | client = container_of(fe, struct smsdvb_client_t, frontend); | 518 | client = container_of(fe, struct smsdvb_client_t, frontend); |
354 | 519 | ||
520 | rc = smsdvb_send_statistics_request(client); | ||
521 | |||
355 | *ber = client->sms_stat_dvb.ReceptionData.BER; | 522 | *ber = client->sms_stat_dvb.ReceptionData.BER; |
356 | 523 | ||
357 | led_feedback(client); | 524 | led_feedback(client); |
358 | 525 | ||
359 | return 0; | 526 | return rc; |
360 | } | 527 | } |
361 | 528 | ||
362 | static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength) | 529 | static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength) |
363 | { | 530 | { |
531 | int rc; | ||
532 | |||
364 | struct smsdvb_client_t *client; | 533 | struct smsdvb_client_t *client; |
365 | client = container_of(fe, struct smsdvb_client_t, frontend); | 534 | client = container_of(fe, struct smsdvb_client_t, frontend); |
366 | 535 | ||
536 | rc = smsdvb_send_statistics_request(client); | ||
537 | |||
367 | if (client->sms_stat_dvb.ReceptionData.InBandPwr < -95) | 538 | if (client->sms_stat_dvb.ReceptionData.InBandPwr < -95) |
368 | *strength = 0; | 539 | *strength = 0; |
369 | else if (client->sms_stat_dvb.ReceptionData.InBandPwr > -29) | 540 | else if (client->sms_stat_dvb.ReceptionData.InBandPwr > -29) |
@@ -375,31 +546,37 @@ static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength) | |||
375 | 546 | ||
376 | led_feedback(client); | 547 | led_feedback(client); |
377 | 548 | ||
378 | return 0; | 549 | return rc; |
379 | } | 550 | } |
380 | 551 | ||
381 | static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr) | 552 | static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr) |
382 | { | 553 | { |
554 | int rc; | ||
383 | struct smsdvb_client_t *client; | 555 | struct smsdvb_client_t *client; |
384 | client = container_of(fe, struct smsdvb_client_t, frontend); | 556 | client = container_of(fe, struct smsdvb_client_t, frontend); |
385 | 557 | ||
558 | rc = smsdvb_send_statistics_request(client); | ||
559 | |||
386 | *snr = client->sms_stat_dvb.ReceptionData.SNR; | 560 | *snr = client->sms_stat_dvb.ReceptionData.SNR; |
387 | 561 | ||
388 | led_feedback(client); | 562 | led_feedback(client); |
389 | 563 | ||
390 | return 0; | 564 | return rc; |
391 | } | 565 | } |
392 | 566 | ||
393 | static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) | 567 | static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) |
394 | { | 568 | { |
569 | int rc; | ||
395 | struct smsdvb_client_t *client; | 570 | struct smsdvb_client_t *client; |
396 | client = container_of(fe, struct smsdvb_client_t, frontend); | 571 | client = container_of(fe, struct smsdvb_client_t, frontend); |
397 | 572 | ||
573 | rc = smsdvb_send_statistics_request(client); | ||
574 | |||
398 | *ucblocks = client->sms_stat_dvb.ReceptionData.ErrorTSPackets; | 575 | *ucblocks = client->sms_stat_dvb.ReceptionData.ErrorTSPackets; |
399 | 576 | ||
400 | led_feedback(client); | 577 | led_feedback(client); |
401 | 578 | ||
402 | return 0; | 579 | return rc; |
403 | } | 580 | } |
404 | 581 | ||
405 | static int smsdvb_get_tune_settings(struct dvb_frontend *fe, | 582 | static int smsdvb_get_tune_settings(struct dvb_frontend *fe, |
@@ -413,9 +590,10 @@ static int smsdvb_get_tune_settings(struct dvb_frontend *fe, | |||
413 | return 0; | 590 | return 0; |
414 | } | 591 | } |
415 | 592 | ||
416 | static int smsdvb_set_frontend(struct dvb_frontend *fe, | 593 | static int smsdvb_dvbt_set_frontend(struct dvb_frontend *fe, |
417 | struct dvb_frontend_parameters *fep) | 594 | struct dvb_frontend_parameters *p) |
418 | { | 595 | { |
596 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
419 | struct smsdvb_client_t *client = | 597 | struct smsdvb_client_t *client = |
420 | container_of(fe, struct smsdvb_client_t, frontend); | 598 | container_of(fe, struct smsdvb_client_t, frontend); |
421 | 599 | ||
@@ -429,24 +607,33 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe, | |||
429 | client->fe_status = FE_HAS_SIGNAL; | 607 | client->fe_status = FE_HAS_SIGNAL; |
430 | client->event_fe_state = -1; | 608 | client->event_fe_state = -1; |
431 | client->event_unc_state = -1; | 609 | client->event_unc_state = -1; |
610 | fe->dtv_property_cache.delivery_system = SYS_DVBT; | ||
432 | 611 | ||
433 | Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; | 612 | Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; |
434 | Msg.Msg.msgDstId = HIF_TASK; | 613 | Msg.Msg.msgDstId = HIF_TASK; |
435 | Msg.Msg.msgFlags = 0; | 614 | Msg.Msg.msgFlags = 0; |
436 | Msg.Msg.msgType = MSG_SMS_RF_TUNE_REQ; | 615 | Msg.Msg.msgType = MSG_SMS_RF_TUNE_REQ; |
437 | Msg.Msg.msgLength = sizeof(Msg); | 616 | Msg.Msg.msgLength = sizeof(Msg); |
438 | Msg.Data[0] = fep->frequency; | 617 | Msg.Data[0] = c->frequency; |
439 | Msg.Data[2] = 12000000; | 618 | Msg.Data[2] = 12000000; |
440 | 619 | ||
441 | sms_debug("freq %d band %d", | 620 | sms_info("%s: freq %d band %d", __func__, c->frequency, |
442 | fep->frequency, fep->u.ofdm.bandwidth); | 621 | c->bandwidth_hz); |
443 | 622 | ||
444 | switch (fep->u.ofdm.bandwidth) { | 623 | switch (c->bandwidth_hz / 1000000) { |
445 | case BANDWIDTH_8_MHZ: Msg.Data[1] = BW_8_MHZ; break; | 624 | case 8: |
446 | case BANDWIDTH_7_MHZ: Msg.Data[1] = BW_7_MHZ; break; | 625 | Msg.Data[1] = BW_8_MHZ; |
447 | case BANDWIDTH_6_MHZ: Msg.Data[1] = BW_6_MHZ; break; | 626 | break; |
448 | case BANDWIDTH_AUTO: return -EOPNOTSUPP; | 627 | case 7: |
449 | default: return -EINVAL; | 628 | Msg.Data[1] = BW_7_MHZ; |
629 | break; | ||
630 | case 6: | ||
631 | Msg.Data[1] = BW_6_MHZ; | ||
632 | break; | ||
633 | case 0: | ||
634 | return -EOPNOTSUPP; | ||
635 | default: | ||
636 | return -EINVAL; | ||
450 | } | 637 | } |
451 | /* Disable LNA, if any. An error is returned if no LNA is present */ | 638 | /* Disable LNA, if any. An error is returned if no LNA is present */ |
452 | ret = sms_board_lna_control(client->coredev, 0); | 639 | ret = sms_board_lna_control(client->coredev, 0); |
@@ -470,6 +657,90 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe, | |||
470 | &client->tune_done); | 657 | &client->tune_done); |
471 | } | 658 | } |
472 | 659 | ||
660 | static int smsdvb_isdbt_set_frontend(struct dvb_frontend *fe, | ||
661 | struct dvb_frontend_parameters *p) | ||
662 | { | ||
663 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
664 | struct smsdvb_client_t *client = | ||
665 | container_of(fe, struct smsdvb_client_t, frontend); | ||
666 | |||
667 | struct { | ||
668 | struct SmsMsgHdr_ST Msg; | ||
669 | u32 Data[4]; | ||
670 | } Msg; | ||
671 | |||
672 | fe->dtv_property_cache.delivery_system = SYS_ISDBT; | ||
673 | |||
674 | Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; | ||
675 | Msg.Msg.msgDstId = HIF_TASK; | ||
676 | Msg.Msg.msgFlags = 0; | ||
677 | Msg.Msg.msgType = MSG_SMS_ISDBT_TUNE_REQ; | ||
678 | Msg.Msg.msgLength = sizeof(Msg); | ||
679 | |||
680 | if (c->isdbt_sb_segment_idx == -1) | ||
681 | c->isdbt_sb_segment_idx = 0; | ||
682 | |||
683 | switch (c->isdbt_sb_segment_count) { | ||
684 | case 3: | ||
685 | Msg.Data[1] = BW_ISDBT_3SEG; | ||
686 | break; | ||
687 | case 1: | ||
688 | Msg.Data[1] = BW_ISDBT_1SEG; | ||
689 | break; | ||
690 | case 0: /* AUTO */ | ||
691 | switch (c->bandwidth_hz / 1000000) { | ||
692 | case 8: | ||
693 | case 7: | ||
694 | c->isdbt_sb_segment_count = 3; | ||
695 | Msg.Data[1] = BW_ISDBT_3SEG; | ||
696 | break; | ||
697 | case 6: | ||
698 | c->isdbt_sb_segment_count = 1; | ||
699 | Msg.Data[1] = BW_ISDBT_1SEG; | ||
700 | break; | ||
701 | default: /* Assumes 6 MHZ bw */ | ||
702 | c->isdbt_sb_segment_count = 1; | ||
703 | c->bandwidth_hz = 6000; | ||
704 | Msg.Data[1] = BW_ISDBT_1SEG; | ||
705 | break; | ||
706 | } | ||
707 | break; | ||
708 | default: | ||
709 | sms_info("Segment count %d not supported", c->isdbt_sb_segment_count); | ||
710 | return -EINVAL; | ||
711 | } | ||
712 | |||
713 | Msg.Data[0] = c->frequency; | ||
714 | Msg.Data[2] = 12000000; | ||
715 | Msg.Data[3] = c->isdbt_sb_segment_idx; | ||
716 | |||
717 | sms_info("%s: freq %d segwidth %d segindex %d\n", __func__, | ||
718 | c->frequency, c->isdbt_sb_segment_count, | ||
719 | c->isdbt_sb_segment_idx); | ||
720 | |||
721 | return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), | ||
722 | &client->tune_done); | ||
723 | } | ||
724 | |||
725 | static int smsdvb_set_frontend(struct dvb_frontend *fe, | ||
726 | struct dvb_frontend_parameters *fep) | ||
727 | { | ||
728 | struct smsdvb_client_t *client = | ||
729 | container_of(fe, struct smsdvb_client_t, frontend); | ||
730 | struct smscore_device_t *coredev = client->coredev; | ||
731 | |||
732 | switch (smscore_get_device_mode(coredev)) { | ||
733 | case DEVICE_MODE_DVBT: | ||
734 | case DEVICE_MODE_DVBT_BDA: | ||
735 | return smsdvb_dvbt_set_frontend(fe, fep); | ||
736 | case DEVICE_MODE_ISDBT: | ||
737 | case DEVICE_MODE_ISDBT_BDA: | ||
738 | return smsdvb_isdbt_set_frontend(fe, fep); | ||
739 | default: | ||
740 | return -EINVAL; | ||
741 | } | ||
742 | } | ||
743 | |||
473 | static int smsdvb_get_frontend(struct dvb_frontend *fe, | 744 | static int smsdvb_get_frontend(struct dvb_frontend *fe, |
474 | struct dvb_frontend_parameters *fep) | 745 | struct dvb_frontend_parameters *fep) |
475 | { | 746 | { |
@@ -557,13 +828,6 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, | |||
557 | /* device removal handled by onremove callback */ | 828 | /* device removal handled by onremove callback */ |
558 | if (!arrival) | 829 | if (!arrival) |
559 | return 0; | 830 | return 0; |
560 | |||
561 | if (smscore_get_device_mode(coredev) != DEVICE_MODE_DVBT_BDA) { | ||
562 | sms_err("SMS Device mode is not set for " | ||
563 | "DVB operation."); | ||
564 | return 0; | ||
565 | } | ||
566 | |||
567 | client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL); | 831 | client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL); |
568 | if (!client) { | 832 | if (!client) { |
569 | sms_err("kmalloc() failed"); | 833 | sms_err("kmalloc() failed"); |
diff --git a/drivers/media/dvb/siano/smsir.c b/drivers/media/dvb/siano/smsir.c index e3d776feeaca..a56eac76e0f0 100644 --- a/drivers/media/dvb/siano/smsir.c +++ b/drivers/media/dvb/siano/smsir.c | |||
@@ -85,9 +85,9 @@ static struct keyboard_layout_map_t keyboard_layout_maps[] = { | |||
85 | { } /* Terminating entry */ | 85 | { } /* Terminating entry */ |
86 | }; | 86 | }; |
87 | 87 | ||
88 | u32 ir_pos; | 88 | static u32 ir_pos; |
89 | u32 ir_word; | 89 | static u32 ir_word; |
90 | u32 ir_toggle; | 90 | static u32 ir_toggle; |
91 | 91 | ||
92 | #define RC5_PUSH_BIT(dst, bit, pos) \ | 92 | #define RC5_PUSH_BIT(dst, bit, pos) \ |
93 | { dst <<= 1; dst |= bit; pos++; } | 93 | { dst <<= 1; dst |= bit; pos++; } |
diff --git a/drivers/media/dvb/ttpci/av7110_ir.c b/drivers/media/dvb/ttpci/av7110_ir.c index 23a1c6380d3f..b070e88d8c6b 100644 --- a/drivers/media/dvb/ttpci/av7110_ir.c +++ b/drivers/media/dvb/ttpci/av7110_ir.c | |||
@@ -268,8 +268,8 @@ int av7110_check_ir_config(struct av7110 *av7110, int force) | |||
268 | 268 | ||
269 | 269 | ||
270 | /* /proc/av7110_ir interface */ | 270 | /* /proc/av7110_ir interface */ |
271 | static int av7110_ir_write_proc(struct file *file, const char __user *buffer, | 271 | static ssize_t av7110_ir_proc_write(struct file *file, const char __user *buffer, |
272 | unsigned long count, void *data) | 272 | size_t count, loff_t *pos) |
273 | { | 273 | { |
274 | char *page; | 274 | char *page; |
275 | u32 ir_config; | 275 | u32 ir_config; |
@@ -309,6 +309,10 @@ static int av7110_ir_write_proc(struct file *file, const char __user *buffer, | |||
309 | return count; | 309 | return count; |
310 | } | 310 | } |
311 | 311 | ||
312 | static const struct file_operations av7110_ir_proc_fops = { | ||
313 | .owner = THIS_MODULE, | ||
314 | .write = av7110_ir_proc_write, | ||
315 | }; | ||
312 | 316 | ||
313 | /* interrupt handler */ | 317 | /* interrupt handler */ |
314 | static void ir_handler(struct av7110 *av7110, u32 ircom) | 318 | static void ir_handler(struct av7110 *av7110, u32 ircom) |
@@ -368,11 +372,9 @@ int __devinit av7110_ir_init(struct av7110 *av7110) | |||
368 | input_dev->timer.data = (unsigned long) &av7110->ir; | 372 | input_dev->timer.data = (unsigned long) &av7110->ir; |
369 | 373 | ||
370 | if (av_cnt == 1) { | 374 | if (av_cnt == 1) { |
371 | e = create_proc_entry("av7110_ir", S_IFREG | S_IRUGO | S_IWUSR, NULL); | 375 | e = proc_create("av7110_ir", S_IWUSR, NULL, &av7110_ir_proc_fops); |
372 | if (e) { | 376 | if (e) |
373 | e->write_proc = av7110_ir_write_proc; | ||
374 | e->size = 4 + 256 * sizeof(u16); | 377 | e->size = 4 + 256 * sizeof(u16); |
375 | } | ||
376 | } | 378 | } |
377 | 379 | ||
378 | tasklet_init(&av7110->ir.ir_tasklet, av7110_emit_key, (unsigned long) &av7110->ir); | 380 | tasklet_init(&av7110->ir.ir_tasklet, av7110_emit_key, (unsigned long) &av7110->ir); |
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c index 9782e0593733..49c2a817a06f 100644 --- a/drivers/media/dvb/ttpci/budget-ci.c +++ b/drivers/media/dvb/ttpci/budget-ci.c | |||
@@ -254,7 +254,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci) | |||
254 | budget_ci->ir.timer_keyup.function = msp430_ir_keyup; | 254 | budget_ci->ir.timer_keyup.function = msp430_ir_keyup; |
255 | budget_ci->ir.timer_keyup.data = (unsigned long) &budget_ci->ir; | 255 | budget_ci->ir.timer_keyup.data = (unsigned long) &budget_ci->ir; |
256 | budget_ci->ir.last_raw = 0xffff; /* An impossible value */ | 256 | budget_ci->ir.last_raw = 0xffff; /* An impossible value */ |
257 | error = ir_input_register(input_dev, ir_codes); | 257 | error = ir_input_register(input_dev, ir_codes, NULL); |
258 | if (error) { | 258 | if (error) { |
259 | printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error); | 259 | printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error); |
260 | return error; | 260 | return error; |
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c index e48380c48990..9fdf26cc6998 100644 --- a/drivers/media/dvb/ttpci/budget.c +++ b/drivers/media/dvb/ttpci/budget.c | |||
@@ -433,9 +433,8 @@ static struct stv090x_config tt1600_stv090x_config = { | |||
433 | .demod_mode = STV090x_SINGLE, | 433 | .demod_mode = STV090x_SINGLE, |
434 | .clk_mode = STV090x_CLK_EXT, | 434 | .clk_mode = STV090x_CLK_EXT, |
435 | 435 | ||
436 | .xtal = 27000000, | 436 | .xtal = 13500000, |
437 | .address = 0x68, | 437 | .address = 0x68, |
438 | .ref_clk = 27000000, | ||
439 | 438 | ||
440 | .ts1_mode = STV090x_TSMODE_DVBCI, | 439 | .ts1_mode = STV090x_TSMODE_DVBCI, |
441 | .ts2_mode = STV090x_TSMODE_SERIAL_CONTINUOUS, | 440 | .ts2_mode = STV090x_TSMODE_SERIAL_CONTINUOUS, |
@@ -457,6 +456,7 @@ static struct stv090x_config tt1600_stv090x_config = { | |||
457 | static struct stv6110x_config tt1600_stv6110x_config = { | 456 | static struct stv6110x_config tt1600_stv6110x_config = { |
458 | .addr = 0x60, | 457 | .addr = 0x60, |
459 | .refclk = 27000000, | 458 | .refclk = 27000000, |
459 | .clk_div = 2, | ||
460 | }; | 460 | }; |
461 | 461 | ||
462 | static struct isl6423_config tt1600_isl6423_config = { | 462 | static struct isl6423_config tt1600_isl6423_config = { |