Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[media] add the support for DiBcom dib8096P

The purpose of this patch is to support the DiBcom chip dib8096P.

Signed-off-by: Olivier Grenie <olivier.grenie@dibcom.fr>
Signed-off-by: Patrick Boettcher <patrick.boettcher@dibcom.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

authored by

Olivier Grenie and committed by
Mauro Carvalho Chehab
0c32dbd7 b293f304

+1019 -93
+5 -5
drivers/media/dvb/dvb-usb/dib0700_devices.c
··· 1279 1279 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); 1280 1280 1281 1281 dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 1282 - 0x80); 1282 + 0x80, 0); 1283 1283 1284 1284 adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, 1285 1285 &dib807x_dib8000_config[0]); ··· 1308 1308 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); 1309 1309 1310 1310 /* initialize IC 0 */ 1311 - dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x80); 1311 + dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x80, 0); 1312 1312 1313 1313 adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, 1314 1314 &dib807x_dib8000_config[0]); ··· 1319 1319 static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap) 1320 1320 { 1321 1321 /* initialize IC 1 */ 1322 - dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x82); 1322 + dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x82, 0); 1323 1323 1324 1324 adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82, 1325 1325 &dib807x_dib8000_config[1]); ··· 1578 1578 msleep(10); 1579 1579 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); 1580 1580 1581 - dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80); 1581 + dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80, 0); 1582 1582 1583 1583 adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]); 1584 1584 ··· 1629 1629 msleep(20); 1630 1630 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); 1631 1631 1632 - dib8000_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, 0x80); 1632 + dib8000_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, 0x80, 0); 1633 1633 1634 1634 adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]); 1635 1635 if (adap->fe_adap[0].fe == NULL)
-7
drivers/media/dvb/frontends/dib7000p.c
··· 81 81 }; 82 82 83 83 /* dib7090 specific fonctions */ 84 - #define MPEG_ON_DIBTX 1 85 - #define DIV_ON_DIBTX 2 86 - #define ADC_ON_DIBTX 3 87 - #define DEMOUT_ON_HOSTBUS 4 88 - #define DIBTX_ON_HOSTBUS 5 89 - #define MPEG_ON_HOSTBUS 6 90 - 91 84 static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode); 92 85 static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff); 93 86 static void dib7090_setDibTxMux(struct dib7000p_state *state, int mode);
+967 -79
drivers/media/dvb/frontends/dib8000.c
··· 81 81 u8 i2c_write_buffer[4]; 82 82 u8 i2c_read_buffer[2]; 83 83 struct mutex i2c_buffer_lock; 84 + u8 input_mode_mpeg; 85 + 86 + u16 tuner_enable; 87 + struct i2c_adapter dib8096p_tuner_adap; 84 88 }; 85 89 86 90 enum dib8000_power_mode { 87 - DIB8000M_POWER_ALL = 0, 88 - DIB8000M_POWER_INTERFACE_ONLY, 91 + DIB8000_POWER_ALL = 0, 92 + DIB8000_POWER_INTERFACE_ONLY, 89 93 }; 90 94 91 95 static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg) ··· 432 428 /* by default everything is going to be powered off */ 433 429 u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0xffff, 434 430 reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3, 431 + reg_1280; 432 + 433 + if (state->revision != 0x8090) 435 434 reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00; 435 + else 436 + reg_1280 = (dib8000_read_word(state, 1280) & 0x707f) | 0x8f80; 436 437 437 438 /* now, depending on the requested mode, we power on */ 438 439 switch (mode) { 439 440 /* power up everything in the demod */ 440 - case DIB8000M_POWER_ALL: 441 + case DIB8000_POWER_ALL: 441 442 reg_774 = 0x0000; 442 443 reg_775 = 0x0000; 443 444 reg_776 = 0x0000; 444 445 reg_900 &= 0xfffc; 445 - reg_1280 &= 0x00ff; 446 + if (state->revision != 0x8090) 447 + reg_1280 &= 0x00ff; 448 + else 449 + reg_1280 &= 0x707f; 446 450 break; 447 - case DIB8000M_POWER_INTERFACE_ONLY: 448 - reg_1280 &= 0x00ff; 451 + case DIB8000_POWER_INTERFACE_ONLY: 452 + if (state->revision != 0x8090) 453 + reg_1280 &= 0x00ff; 454 + else 455 + reg_1280 &= 0xfa7b; 449 456 break; 450 457 } 451 458 ··· 468 453 dib8000_write_word(state, 1280, reg_1280); 469 454 } 470 455 456 + static int dib8000_init_sdram(struct dib8000_state *state) 457 + { 458 + u16 reg = 0; 459 + dprintk("Init sdram"); 460 + 461 + reg = dib8000_read_word(state, 274)&0xfff0; 462 + /* P_dintlv_delay_ram = 7 because of MobileSdram */ 463 + dib8000_write_word(state, 274, reg | 0x7); 464 + 465 + dib8000_write_word(state, 1803, (7<<2)); 466 + 467 + reg = dib8000_read_word(state, 1280); 468 + /* force restart P_restart_sdram */ 469 + dib8000_write_word(state, 1280, reg | (1<<2)); 470 + 471 + /* release restart P_restart_sdram */ 472 + dib8000_write_word(state, 1280, reg); 473 + 474 + return 0; 475 + } 476 + 471 477 static int dib8000_set_adc_state(struct dib8000_state *state, enum dibx000_adc_states no) 472 478 { 473 479 int ret = 0; 474 - u16 reg_907 = dib8000_read_word(state, 907), reg_908 = dib8000_read_word(state, 908); 480 + u16 reg, reg_907 = dib8000_read_word(state, 907); 481 + u16 reg_908 = dib8000_read_word(state, 908); 475 482 476 483 switch (no) { 477 484 case DIBX000_SLOW_ADC_ON: 478 - reg_908 |= (1 << 1) | (1 << 0); 479 - ret |= dib8000_write_word(state, 908, reg_908); 480 - reg_908 &= ~(1 << 1); 485 + if (state->revision != 0x8090) { 486 + reg_908 |= (1 << 1) | (1 << 0); 487 + ret |= dib8000_write_word(state, 908, reg_908); 488 + reg_908 &= ~(1 << 1); 489 + } else { 490 + reg = dib8000_read_word(state, 1925); 491 + /* en_slowAdc = 1 & reset_sladc = 1 */ 492 + dib8000_write_word(state, 1925, reg | 493 + (1<<4) | (1<<2)); 494 + 495 + /* read acces to make it works... strange ... */ 496 + reg = dib8000_read_word(state, 1925); 497 + msleep(20); 498 + /* en_slowAdc = 1 & reset_sladc = 0 */ 499 + dib8000_write_word(state, 1925, reg & ~(1<<4)); 500 + 501 + reg = dib8000_read_word(state, 921) & ~((0x3 << 14) 502 + | (0x3 << 12)); 503 + /* ref = Vin1 => Vbg ; sel = Vin0 or Vin3 ; 504 + (Vin2 = Vcm) */ 505 + dib8000_write_word(state, 921, reg | (1 << 14) 506 + | (3 << 12)); 507 + } 481 508 break; 482 509 483 510 case DIBX000_SLOW_ADC_OFF: 511 + if (state->revision == 0x8090) { 512 + reg = dib8000_read_word(state, 1925); 513 + /* reset_sladc = 1 en_slowAdc = 0 */ 514 + dib8000_write_word(state, 1925, 515 + (reg & ~(1<<2)) | (1<<4)); 516 + } 484 517 reg_908 |= (1 << 1) | (1 << 0); 485 518 break; 486 519 ··· 584 521 585 522 static int dib8000_sad_calib(struct dib8000_state *state) 586 523 { 587 - /* internal */ 524 + if (state->revision == 0x8090) { 525 + dprintk("%s: the sad calibration is not needed for the dib8096P", 526 + __func__); 527 + return 0; 528 + } 529 + /* internal */ 588 530 dib8000_write_word(state, 923, (0 << 1) | (0 << 0)); 589 531 dib8000_write_word(state, 924, 776); // 0.625*3.3 / 4096 590 532 ··· 614 546 static void dib8000_reset_pll_common(struct dib8000_state *state, const struct dibx000_bandwidth_config *bw) 615 547 { 616 548 dprintk("ifreq: %d %x, inversion: %d", bw->ifreq, bw->ifreq, bw->ifreq >> 25); 617 - dib8000_write_word(state, 23, (u16) (((bw->internal * 1000) >> 16) & 0xffff)); /* P_sec_len */ 618 - dib8000_write_word(state, 24, (u16) ((bw->internal * 1000) & 0xffff)); 549 + if (state->revision != 0x8090) { 550 + dib8000_write_word(state, 23, 551 + (u16) (((bw->internal * 1000) >> 16) & 0xffff)); 552 + dib8000_write_word(state, 24, 553 + (u16) ((bw->internal * 1000) & 0xffff)); 554 + } else { 555 + dib8000_write_word(state, 23, (u16) (((bw->internal / 2 * 1000) >> 16) & 0xffff)); 556 + dib8000_write_word(state, 24, 557 + (u16) ((bw->internal / 2 * 1000) & 0xffff)); 558 + } 619 559 dib8000_write_word(state, 27, (u16) ((bw->ifreq >> 16) & 0x01ff)); 620 560 dib8000_write_word(state, 28, (u16) (bw->ifreq & 0xffff)); 621 561 dib8000_write_word(state, 26, (u16) ((bw->ifreq >> 25) & 0x0003)); 622 562 623 - dib8000_write_word(state, 922, bw->sad_cfg); 563 + if (state->revision != 0x8090) 564 + dib8000_write_word(state, 922, bw->sad_cfg); 624 565 } 625 566 626 567 static void dib8000_reset_pll(struct dib8000_state *state) 627 568 { 628 569 const struct dibx000_bandwidth_config *pll = state->cfg.pll; 629 - u16 clk_cfg1; 570 + u16 clk_cfg1, reg; 630 571 631 - // clk_cfg0 632 - dib8000_write_word(state, 901, (pll->pll_prediv << 8) | (pll->pll_ratio << 0)); 572 + if (state->revision != 0x8090) { 573 + dib8000_write_word(state, 901, 574 + (pll->pll_prediv << 8) | (pll->pll_ratio << 0)); 633 575 634 - // clk_cfg1 635 - clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) | 636 - (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) | (1 << 3) | 637 - (pll->pll_range << 1) | (pll->pll_reset << 0); 576 + clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) | 577 + (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) | 578 + (1 << 3) | (pll->pll_range << 1) | 579 + (pll->pll_reset << 0); 638 580 639 - dib8000_write_word(state, 902, clk_cfg1); 640 - clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3); 641 - dib8000_write_word(state, 902, clk_cfg1); 581 + dib8000_write_word(state, 902, clk_cfg1); 582 + clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3); 583 + dib8000_write_word(state, 902, clk_cfg1); 642 584 643 - dprintk("clk_cfg1: 0x%04x", clk_cfg1); /* 0x507 1 0 1 000 0 0 11 1 */ 585 + dprintk("clk_cfg1: 0x%04x", clk_cfg1); 644 586 645 - /* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */ 646 - if (state->cfg.pll->ADClkSrc == 0) 647 - dib8000_write_word(state, 904, (0 << 15) | (0 << 12) | (0 << 10) | 648 - (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1)); 649 - else if (state->cfg.refclksel != 0) 650 - dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | 651 - ((state->cfg.refclksel & 0x3) << 10) | (pll->modulo << 8) | 652 - (pll->ADClkSrc << 7) | (0 << 1)); 653 - else 654 - dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | (3 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1)); 587 + /* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */ 588 + if (state->cfg.pll->ADClkSrc == 0) 589 + dib8000_write_word(state, 904, 590 + (0 << 15) | (0 << 12) | (0 << 10) | 591 + (pll->modulo << 8) | 592 + (pll->ADClkSrc << 7) | (0 << 1)); 593 + else if (state->cfg.refclksel != 0) 594 + dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | 595 + ((state->cfg.refclksel & 0x3) << 10) | 596 + (pll->modulo << 8) | 597 + (pll->ADClkSrc << 7) | (0 << 1)); 598 + else 599 + dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | 600 + (3 << 10) | (pll->modulo << 8) | 601 + (pll->ADClkSrc << 7) | (0 << 1)); 602 + } else { 603 + dib8000_write_word(state, 1856, (!pll->pll_reset<<13) | 604 + (pll->pll_range<<12) | (pll->pll_ratio<<6) | 605 + (pll->pll_prediv)); 606 + 607 + reg = dib8000_read_word(state, 1857); 608 + dib8000_write_word(state, 1857, reg|(!pll->pll_bypass<<15)); 609 + 610 + reg = dib8000_read_word(state, 1858); /* Force clk out pll /2 */ 611 + dib8000_write_word(state, 1858, reg | 1); 612 + 613 + dib8000_write_word(state, 904, (pll->modulo << 8)); 614 + } 655 615 656 616 dib8000_reset_pll_common(state, pll); 657 617 } 618 + 619 + int dib8000_update_pll(struct dvb_frontend *fe, 620 + struct dibx000_bandwidth_config *pll) 621 + { 622 + struct dib8000_state *state = fe->demodulator_priv; 623 + u16 reg_1857, reg_1856 = dib8000_read_word(state, 1856); 624 + u8 loopdiv, prediv; 625 + u32 internal, xtal; 626 + 627 + /* get back old values */ 628 + prediv = reg_1856 & 0x3f; 629 + loopdiv = (reg_1856 >> 6) & 0x3f; 630 + 631 + if ((pll != NULL) && (pll->pll_prediv != prediv || 632 + pll->pll_ratio != loopdiv)) { 633 + dprintk("Updating pll (prediv: old = %d new = %d ; loopdiv : old = %d new = %d)", prediv, pll->pll_prediv, loopdiv, pll->pll_ratio); 634 + reg_1856 &= 0xf000; 635 + reg_1857 = dib8000_read_word(state, 1857); 636 + /* disable PLL */ 637 + dib8000_write_word(state, 1857, reg_1857 & ~(1 << 15)); 638 + 639 + dib8000_write_word(state, 1856, reg_1856 | 640 + ((pll->pll_ratio & 0x3f) << 6) | 641 + (pll->pll_prediv & 0x3f)); 642 + 643 + /* write new system clk into P_sec_len */ 644 + internal = dib8000_read32(state, 23) / 1000; 645 + dprintk("Old Internal = %d", internal); 646 + xtal = 2 * (internal / loopdiv) * prediv; 647 + internal = 1000 * (xtal/pll->pll_prediv) * pll->pll_ratio; 648 + dprintk("Xtal = %d , New Fmem = %d New Fdemod = %d, New Fsampling = %d", xtal, internal/1000, internal/2000, internal/8000); 649 + dprintk("New Internal = %d", internal); 650 + 651 + dib8000_write_word(state, 23, 652 + (u16) (((internal / 2) >> 16) & 0xffff)); 653 + dib8000_write_word(state, 24, (u16) ((internal / 2) & 0xffff)); 654 + /* enable PLL */ 655 + dib8000_write_word(state, 1857, reg_1857 | (1 << 15)); 656 + 657 + while (((dib8000_read_word(state, 1856)>>15)&0x1) != 1) 658 + dprintk("Waiting for PLL to lock"); 659 + 660 + /* verify */ 661 + reg_1856 = dib8000_read_word(state, 1856); 662 + dprintk("PLL Updated with prediv = %d and loopdiv = %d", 663 + reg_1856&0x3f, (reg_1856>>6)&0x3f); 664 + 665 + return 0; 666 + } 667 + return -EINVAL; 668 + } 669 + EXPORT_SYMBOL(dib8000_update_pll); 670 + 658 671 659 672 static int dib8000_reset_gpio(struct dib8000_state *st) 660 673 { ··· 870 721 (3 << 5) | /* P_ctrl_pre_freq_step=3 */ 871 722 (1 << 0), /* P_pre_freq_win_len=1 */ 872 723 873 - 1, 903, 874 - (0 << 4) | 2, // P_divclksel=0 P_divbitsel=2 (was clk=3,bit=1 for MPW) 875 - 876 724 0, 877 725 }; 878 726 ··· 886 740 } 887 741 888 742 value = dib8000_i2c_read16(client, 897); 889 - if (value != 0x8000 && value != 0x8001 && value != 0x8002) { 743 + if (value != 0x8000 && value != 0x8001 && 744 + value != 0x8002 && value != 0x8090) { 890 745 dprintk("wrong Device ID (%x)", value); 891 746 return 0; 892 747 } ··· 902 755 case 0x8002: 903 756 dprintk("found DiB8000C"); 904 757 break; 758 + case 0x8090: 759 + dprintk("found DiB8096P"); 760 + break; 905 761 } 906 762 return value; 907 763 } ··· 913 763 { 914 764 struct dib8000_state *state = fe->demodulator_priv; 915 765 916 - dib8000_write_word(state, 1287, 0x0003); /* sram lead in, rdy */ 917 - 918 766 if ((state->revision = dib8000_identify(&state->i2c)) == 0) 919 767 return -EINVAL; 768 + 769 + /* sram lead in, rdy */ 770 + if (state->revision != 0x8090) 771 + dib8000_write_word(state, 1287, 0x0003); 920 772 921 773 if (state->revision == 0x8000) 922 774 dprintk("error : dib8000 MA not supported"); 923 775 924 776 dibx000_reset_i2c_master(&state->i2c_master); 925 777 926 - dib8000_set_power_mode(state, DIB8000M_POWER_ALL); 778 + dib8000_set_power_mode(state, DIB8000_POWER_ALL); 927 779 928 780 /* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */ 929 781 dib8000_set_adc_state(state, DIBX000_VBG_ENABLE); ··· 934 782 dib8000_write_word(state, 770, 0xffff); 935 783 dib8000_write_word(state, 771, 0xffff); 936 784 dib8000_write_word(state, 772, 0xfffc); 937 - dib8000_write_word(state, 898, 0x000c); // sad 938 - dib8000_write_word(state, 1280, 0x004d); 785 + if (state->revision == 0x8090) 786 + dib8000_write_word(state, 1280, 0x0045); 787 + else 788 + dib8000_write_word(state, 1280, 0x004d); 939 789 dib8000_write_word(state, 1281, 0x000c); 940 790 941 791 dib8000_write_word(state, 770, 0x0000); ··· 948 794 dib8000_write_word(state, 1281, 0x0000); 949 795 950 796 /* drives */ 951 - if (state->cfg.drives) 952 - dib8000_write_word(state, 906, state->cfg.drives); 953 - else { 954 - dprintk("using standard PAD-drive-settings, please adjust settings in config-struct to be optimal."); 955 - dib8000_write_word(state, 906, 0x2d98); // min drive SDRAM - not optimal - adjust 797 + if (state->revision != 0x8090) { 798 + if (state->cfg.drives) 799 + dib8000_write_word(state, 906, state->cfg.drives); 800 + else { 801 + dprintk("using standard PAD-drive-settings, please adjust settings in config-struct to be optimal."); 802 + /* min drive SDRAM - not optimal - adjust */ 803 + dib8000_write_word(state, 906, 0x2d98); 804 + } 956 805 } 957 806 958 807 dib8000_reset_pll(state); 808 + if (state->revision != 0x8090) 809 + dib8000_write_word(state, 898, 0x0004); 959 810 960 811 if (dib8000_reset_gpio(state) != 0) 961 812 dprintk("GPIO reset was not successful."); 962 813 963 - if (dib8000_set_output_mode(fe, OUTMODE_HIGH_Z) != 0) 814 + if ((state->revision != 0x8090) && 815 + (dib8000_set_output_mode(fe, OUTMODE_HIGH_Z) != 0)) 964 816 dprintk("OUTPUT_MODE could not be resetted."); 965 817 966 818 state->current_agc = NULL; ··· 992 832 l = *n++; 993 833 } 994 834 } 835 + if (state->revision != 0x8090) 836 + dib8000_write_word(state, 903, (0 << 4) | 2); 995 837 state->isdbt_cfg_loaded = 0; 996 838 997 839 //div_cfg override for special configs ··· 1006 844 dib8000_set_bandwidth(fe, 6000); 1007 845 1008 846 dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON); 1009 - dib8000_sad_calib(state); 1010 - dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF); 847 + if (state->revision != 0x8090) { 848 + dib8000_sad_calib(state); 849 + dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF); 850 + } 1011 851 1012 - dib8000_set_power_mode(state, DIB8000M_POWER_INTERFACE_ONLY); 852 + dib8000_set_power_mode(state, DIB8000_POWER_INTERFACE_ONLY); 1013 853 1014 854 return 0; 1015 855 } ··· 1043 879 { 1044 880 struct dibx000_agc_config *agc = NULL; 1045 881 int i; 882 + u16 reg; 883 + 1046 884 if (state->current_band == band && state->current_agc != NULL) 1047 885 return 0; 1048 886 state->current_band = band; ··· 1080 914 dib8000_write_word(state, 106, state->wbd_ref); 1081 915 else // use default 1082 916 dib8000_write_word(state, 106, agc->wbd_ref); 917 + 918 + if (state->revision == 0x8090) { 919 + reg = dib8000_read_word(state, 922) & (0x3 << 2); 920 + dib8000_write_word(state, 922, reg | (agc->wbd_sel << 2)); 921 + } 922 + 1083 923 dib8000_write_word(state, 107, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8)); 1084 924 dib8000_write_word(state, 108, agc->agc1_max); 1085 925 dib8000_write_word(state, 109, agc->agc1_min); ··· 1097 925 dib8000_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2); 1098 926 1099 927 dib8000_write_word(state, 75, agc->agc1_pt3); 1100 - dib8000_write_word(state, 923, (dib8000_read_word(state, 923) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2)); /*LB : 929 -> 923 */ 928 + if (state->revision != 0x8090) 929 + dib8000_write_word(state, 923, 930 + (dib8000_read_word(state, 923) & 0xffe3) | 931 + (agc->wbd_inv << 4) | (agc->wbd_sel << 2)); 1101 932 1102 933 return 0; 1103 934 } ··· 1143 968 { 1144 969 struct dib8000_state *state = fe->demodulator_priv; 1145 970 enum frontend_tune_state *tune_state = &state->tune_state; 1146 - 1147 971 int ret = 0; 972 + u16 reg, upd_demod_gain_period = 0x8000; 1148 973 1149 974 switch (*tune_state) { 1150 975 case CT_AGC_START: 1151 976 // set power-up level: interf+analog+AGC 1152 977 1153 - dib8000_set_adc_state(state, DIBX000_ADC_ON); 978 + if (state->revision != 0x8090) 979 + dib8000_set_adc_state(state, DIBX000_ADC_ON); 980 + else { 981 + dib8000_set_power_mode(state, DIB8000_POWER_ALL); 982 + 983 + reg = dib8000_read_word(state, 1947)&0xff00; 984 + dib8000_write_word(state, 1946, 985 + upd_demod_gain_period & 0xFFFF); 986 + /* bit 14 = enDemodGain */ 987 + dib8000_write_word(state, 1947, reg | (1<<14) | 988 + ((upd_demod_gain_period >> 16) & 0xFF)); 989 + 990 + /* enable adc i & q */ 991 + reg = dib8000_read_word(state, 1920); 992 + dib8000_write_word(state, 1920, (reg | 0x3) & 993 + (~(1 << 7))); 994 + } 1154 995 1155 996 if (dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000))) != 0) { 1156 997 *tune_state = CT_AGC_STOP; ··· 1217 1026 1218 1027 } 1219 1028 1029 + static void dib8096p_host_bus_drive(struct dib8000_state *state, u8 drive) 1030 + { 1031 + u16 reg; 1032 + 1033 + drive &= 0x7; 1034 + 1035 + /* drive host bus 2, 3, 4 */ 1036 + reg = dib8000_read_word(state, 1798) & 1037 + ~(0x7 | (0x7 << 6) | (0x7 << 12)); 1038 + reg |= (drive<<12) | (drive<<6) | drive; 1039 + dib8000_write_word(state, 1798, reg); 1040 + 1041 + /* drive host bus 5,6 */ 1042 + reg = dib8000_read_word(state, 1799) & ~((0x7 << 2) | (0x7 << 8)); 1043 + reg |= (drive<<8) | (drive<<2); 1044 + dib8000_write_word(state, 1799, reg); 1045 + 1046 + /* drive host bus 7, 8, 9 */ 1047 + reg = dib8000_read_word(state, 1800) & 1048 + ~(0x7 | (0x7 << 6) | (0x7 << 12)); 1049 + reg |= (drive<<12) | (drive<<6) | drive; 1050 + dib8000_write_word(state, 1800, reg); 1051 + 1052 + /* drive host bus 10, 11 */ 1053 + reg = dib8000_read_word(state, 1801) & ~((0x7 << 2) | (0x7 << 8)); 1054 + reg |= (drive<<8) | (drive<<2); 1055 + dib8000_write_word(state, 1801, reg); 1056 + 1057 + /* drive host bus 12, 13, 14 */ 1058 + reg = dib8000_read_word(state, 1802) & 1059 + ~(0x7 | (0x7 << 6) | (0x7 << 12)); 1060 + reg |= (drive<<12) | (drive<<6) | drive; 1061 + dib8000_write_word(state, 1802, reg); 1062 + } 1063 + 1064 + static u32 dib8096p_calcSyncFreq(u32 P_Kin, u32 P_Kout, 1065 + u32 insertExtSynchro, u32 syncSize) 1066 + { 1067 + u32 quantif = 3; 1068 + u32 nom = (insertExtSynchro * P_Kin+syncSize); 1069 + u32 denom = P_Kout; 1070 + u32 syncFreq = ((nom << quantif) / denom); 1071 + 1072 + if ((syncFreq & ((1 << quantif) - 1)) != 0) 1073 + syncFreq = (syncFreq >> quantif) + 1; 1074 + else 1075 + syncFreq = (syncFreq >> quantif); 1076 + 1077 + if (syncFreq != 0) 1078 + syncFreq = syncFreq - 1; 1079 + 1080 + return syncFreq; 1081 + } 1082 + 1083 + static void dib8096p_cfg_DibTx(struct dib8000_state *state, u32 P_Kin, 1084 + u32 P_Kout, u32 insertExtSynchro, u32 synchroMode, 1085 + u32 syncWord, u32 syncSize) 1086 + { 1087 + dprintk("Configure DibStream Tx"); 1088 + 1089 + dib8000_write_word(state, 1615, 1); 1090 + dib8000_write_word(state, 1603, P_Kin); 1091 + dib8000_write_word(state, 1605, P_Kout); 1092 + dib8000_write_word(state, 1606, insertExtSynchro); 1093 + dib8000_write_word(state, 1608, synchroMode); 1094 + dib8000_write_word(state, 1609, (syncWord >> 16) & 0xffff); 1095 + dib8000_write_word(state, 1610, syncWord & 0xffff); 1096 + dib8000_write_word(state, 1612, syncSize); 1097 + dib8000_write_word(state, 1615, 0); 1098 + } 1099 + 1100 + static void dib8096p_cfg_DibRx(struct dib8000_state *state, u32 P_Kin, 1101 + u32 P_Kout, u32 synchroMode, u32 insertExtSynchro, 1102 + u32 syncWord, u32 syncSize, u32 dataOutRate) 1103 + { 1104 + u32 syncFreq; 1105 + 1106 + dprintk("Configure DibStream Rx synchroMode = %d", synchroMode); 1107 + 1108 + if ((P_Kin != 0) && (P_Kout != 0)) { 1109 + syncFreq = dib8096p_calcSyncFreq(P_Kin, P_Kout, 1110 + insertExtSynchro, syncSize); 1111 + dib8000_write_word(state, 1542, syncFreq); 1112 + } 1113 + 1114 + dib8000_write_word(state, 1554, 1); 1115 + dib8000_write_word(state, 1536, P_Kin); 1116 + dib8000_write_word(state, 1537, P_Kout); 1117 + dib8000_write_word(state, 1539, synchroMode); 1118 + dib8000_write_word(state, 1540, (syncWord >> 16) & 0xffff); 1119 + dib8000_write_word(state, 1541, syncWord & 0xffff); 1120 + dib8000_write_word(state, 1543, syncSize); 1121 + dib8000_write_word(state, 1544, dataOutRate); 1122 + dib8000_write_word(state, 1554, 0); 1123 + } 1124 + 1125 + static void dib8096p_enMpegMux(struct dib8000_state *state, int onoff) 1126 + { 1127 + u16 reg_1287; 1128 + 1129 + reg_1287 = dib8000_read_word(state, 1287); 1130 + 1131 + switch (onoff) { 1132 + case 1: 1133 + reg_1287 &= ~(1 << 8); 1134 + break; 1135 + case 0: 1136 + reg_1287 |= (1 << 8); 1137 + break; 1138 + } 1139 + 1140 + dib8000_write_word(state, 1287, reg_1287); 1141 + } 1142 + 1143 + static void dib8096p_configMpegMux(struct dib8000_state *state, 1144 + u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2) 1145 + { 1146 + u16 reg_1287; 1147 + 1148 + dprintk("Enable Mpeg mux"); 1149 + 1150 + dib8096p_enMpegMux(state, 0); 1151 + 1152 + /* If the input mode is MPEG do not divide the serial clock */ 1153 + if ((enSerialMode == 1) && (state->input_mode_mpeg == 1)) 1154 + enSerialClkDiv2 = 0; 1155 + 1156 + reg_1287 = ((pulseWidth & 0x1f) << 3) | 1157 + ((enSerialMode & 0x1) << 2) | (enSerialClkDiv2 & 0x1); 1158 + dib8000_write_word(state, 1287, reg_1287); 1159 + 1160 + dib8096p_enMpegMux(state, 1); 1161 + } 1162 + 1163 + static void dib8096p_setDibTxMux(struct dib8000_state *state, int mode) 1164 + { 1165 + u16 reg_1288 = dib8000_read_word(state, 1288) & ~(0x7 << 7); 1166 + 1167 + switch (mode) { 1168 + case MPEG_ON_DIBTX: 1169 + dprintk("SET MPEG ON DIBSTREAM TX"); 1170 + dib8096p_cfg_DibTx(state, 8, 5, 0, 0, 0, 0); 1171 + reg_1288 |= (1 << 9); break; 1172 + case DIV_ON_DIBTX: 1173 + dprintk("SET DIV_OUT ON DIBSTREAM TX"); 1174 + dib8096p_cfg_DibTx(state, 5, 5, 0, 0, 0, 0); 1175 + reg_1288 |= (1 << 8); break; 1176 + case ADC_ON_DIBTX: 1177 + dprintk("SET ADC_OUT ON DIBSTREAM TX"); 1178 + dib8096p_cfg_DibTx(state, 20, 5, 10, 0, 0, 0); 1179 + reg_1288 |= (1 << 7); break; 1180 + default: 1181 + break; 1182 + } 1183 + dib8000_write_word(state, 1288, reg_1288); 1184 + } 1185 + 1186 + static void dib8096p_setHostBusMux(struct dib8000_state *state, int mode) 1187 + { 1188 + u16 reg_1288 = dib8000_read_word(state, 1288) & ~(0x7 << 4); 1189 + 1190 + switch (mode) { 1191 + case DEMOUT_ON_HOSTBUS: 1192 + dprintk("SET DEM OUT OLD INTERF ON HOST BUS"); 1193 + dib8096p_enMpegMux(state, 0); 1194 + reg_1288 |= (1 << 6); 1195 + break; 1196 + case DIBTX_ON_HOSTBUS: 1197 + dprintk("SET DIBSTREAM TX ON HOST BUS"); 1198 + dib8096p_enMpegMux(state, 0); 1199 + reg_1288 |= (1 << 5); 1200 + break; 1201 + case MPEG_ON_HOSTBUS: 1202 + dprintk("SET MPEG MUX ON HOST BUS"); 1203 + reg_1288 |= (1 << 4); 1204 + break; 1205 + default: 1206 + break; 1207 + } 1208 + dib8000_write_word(state, 1288, reg_1288); 1209 + } 1210 + 1211 + static int dib8096p_set_diversity_in(struct dvb_frontend *fe, int onoff) 1212 + { 1213 + struct dib8000_state *state = fe->demodulator_priv; 1214 + u16 reg_1287; 1215 + 1216 + switch (onoff) { 1217 + case 0: /* only use the internal way - not the diversity input */ 1218 + dprintk("%s mode OFF : by default Enable Mpeg INPUT", 1219 + __func__); 1220 + /* outputRate = 8 */ 1221 + dib8096p_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); 1222 + 1223 + /* Do not divide the serial clock of MPEG MUX in 1224 + SERIAL MODE in case input mode MPEG is used */ 1225 + reg_1287 = dib8000_read_word(state, 1287); 1226 + /* enSerialClkDiv2 == 1 ? */ 1227 + if ((reg_1287 & 0x1) == 1) { 1228 + /* force enSerialClkDiv2 = 0 */ 1229 + reg_1287 &= ~0x1; 1230 + dib8000_write_word(state, 1287, reg_1287); 1231 + } 1232 + state->input_mode_mpeg = 1; 1233 + break; 1234 + case 1: /* both ways */ 1235 + case 2: /* only the diversity input */ 1236 + dprintk("%s ON : Enable diversity INPUT", __func__); 1237 + dib8096p_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0); 1238 + state->input_mode_mpeg = 0; 1239 + break; 1240 + } 1241 + 1242 + dib8000_set_diversity_in(state->fe[0], onoff); 1243 + return 0; 1244 + } 1245 + 1246 + static int dib8096p_set_output_mode(struct dvb_frontend *fe, int mode) 1247 + { 1248 + struct dib8000_state *state = fe->demodulator_priv; 1249 + u16 outreg, smo_mode, fifo_threshold; 1250 + u8 prefer_mpeg_mux_use = 1; 1251 + int ret = 0; 1252 + 1253 + dib8096p_host_bus_drive(state, 1); 1254 + 1255 + fifo_threshold = 1792; 1256 + smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1); 1257 + outreg = dib8000_read_word(state, 1286) & 1258 + ~((1 << 10) | (0x7 << 6) | (1 << 1)); 1259 + 1260 + switch (mode) { 1261 + case OUTMODE_HIGH_Z: 1262 + outreg = 0; 1263 + break; 1264 + 1265 + case OUTMODE_MPEG2_SERIAL: 1266 + if (prefer_mpeg_mux_use) { 1267 + dprintk("dib8096P setting output mode TS_SERIAL using Mpeg Mux"); 1268 + dib8096p_configMpegMux(state, 3, 1, 1); 1269 + dib8096p_setHostBusMux(state, MPEG_ON_HOSTBUS); 1270 + } else {/* Use Smooth block */ 1271 + dprintk("dib8096P setting output mode TS_SERIAL using Smooth bloc"); 1272 + dib8096p_setHostBusMux(state, 1273 + DEMOUT_ON_HOSTBUS); 1274 + outreg |= (2 << 6) | (0 << 1); 1275 + } 1276 + break; 1277 + 1278 + case OUTMODE_MPEG2_PAR_GATED_CLK: 1279 + if (prefer_mpeg_mux_use) { 1280 + dprintk("dib8096P setting output mode TS_PARALLEL_GATED using Mpeg Mux"); 1281 + dib8096p_configMpegMux(state, 2, 0, 0); 1282 + dib8096p_setHostBusMux(state, MPEG_ON_HOSTBUS); 1283 + } else { /* Use Smooth block */ 1284 + dprintk("dib8096P setting output mode TS_PARALLEL_GATED using Smooth block"); 1285 + dib8096p_setHostBusMux(state, 1286 + DEMOUT_ON_HOSTBUS); 1287 + outreg |= (0 << 6); 1288 + } 1289 + break; 1290 + 1291 + case OUTMODE_MPEG2_PAR_CONT_CLK: /* Using Smooth block only */ 1292 + dprintk("dib8096P setting output mode TS_PARALLEL_CONT using Smooth block"); 1293 + dib8096p_setHostBusMux(state, DEMOUT_ON_HOSTBUS); 1294 + outreg |= (1 << 6); 1295 + break; 1296 + 1297 + case OUTMODE_MPEG2_FIFO: 1298 + /* Using Smooth block because not supported 1299 + by new Mpeg Mux bloc */ 1300 + dprintk("dib8096P setting output mode TS_FIFO using Smooth block"); 1301 + dib8096p_setHostBusMux(state, DEMOUT_ON_HOSTBUS); 1302 + outreg |= (5 << 6); 1303 + smo_mode |= (3 << 1); 1304 + fifo_threshold = 512; 1305 + break; 1306 + 1307 + case OUTMODE_DIVERSITY: 1308 + dprintk("dib8096P setting output mode MODE_DIVERSITY"); 1309 + dib8096p_setDibTxMux(state, DIV_ON_DIBTX); 1310 + dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS); 1311 + break; 1312 + 1313 + case OUTMODE_ANALOG_ADC: 1314 + dprintk("dib8096P setting output mode MODE_ANALOG_ADC"); 1315 + dib8096p_setDibTxMux(state, ADC_ON_DIBTX); 1316 + dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS); 1317 + break; 1318 + } 1319 + 1320 + if (mode != OUTMODE_HIGH_Z) 1321 + outreg |= (1<<10); 1322 + 1323 + dprintk("output_mpeg2_in_188_bytes = %d", 1324 + state->cfg.output_mpeg2_in_188_bytes); 1325 + if (state->cfg.output_mpeg2_in_188_bytes) 1326 + smo_mode |= (1 << 5); 1327 + 1328 + ret |= dib8000_write_word(state, 299, smo_mode); 1329 + /* synchronous fread */ 1330 + ret |= dib8000_write_word(state, 299 + 1, fifo_threshold); 1331 + ret |= dib8000_write_word(state, 1286, outreg); 1332 + 1333 + return ret; 1334 + } 1335 + 1336 + static int map_addr_to_serpar_number(struct i2c_msg *msg) 1337 + { 1338 + if (msg->buf[0] <= 15) 1339 + msg->buf[0] -= 1; 1340 + else if (msg->buf[0] == 17) 1341 + msg->buf[0] = 15; 1342 + else if (msg->buf[0] == 16) 1343 + msg->buf[0] = 17; 1344 + else if (msg->buf[0] == 19) 1345 + msg->buf[0] = 16; 1346 + else if (msg->buf[0] >= 21 && msg->buf[0] <= 25) 1347 + msg->buf[0] -= 3; 1348 + else if (msg->buf[0] == 28) 1349 + msg->buf[0] = 23; 1350 + else if (msg->buf[0] == 99) 1351 + msg->buf[0] = 99; 1352 + else 1353 + return -EINVAL; 1354 + return 0; 1355 + } 1356 + 1357 + static int dib8096p_tuner_write_serpar(struct i2c_adapter *i2c_adap, 1358 + struct i2c_msg msg[], int num) 1359 + { 1360 + struct dib8000_state *state = i2c_get_adapdata(i2c_adap); 1361 + u8 n_overflow = 1; 1362 + u16 i = 1000; 1363 + u16 serpar_num = msg[0].buf[0]; 1364 + 1365 + while (n_overflow == 1 && i) { 1366 + n_overflow = (dib8000_read_word(state, 1984) >> 1) & 0x1; 1367 + i--; 1368 + if (i == 0) 1369 + dprintk("Tuner ITF: write busy (overflow)"); 1370 + } 1371 + dib8000_write_word(state, 1985, (1 << 6) | (serpar_num & 0x3f)); 1372 + dib8000_write_word(state, 1986, (msg[0].buf[1] << 8) | msg[0].buf[2]); 1373 + 1374 + return num; 1375 + } 1376 + 1377 + static int dib8096p_tuner_read_serpar(struct i2c_adapter *i2c_adap, 1378 + struct i2c_msg msg[], int num) 1379 + { 1380 + struct dib8000_state *state = i2c_get_adapdata(i2c_adap); 1381 + u8 n_overflow = 1, n_empty = 1; 1382 + u16 i = 1000; 1383 + u16 serpar_num = msg[0].buf[0]; 1384 + u16 read_word; 1385 + 1386 + while (n_overflow == 1 && i) { 1387 + n_overflow = (dib8000_read_word(state, 1984) >> 1) & 0x1; 1388 + i--; 1389 + if (i == 0) 1390 + dprintk("TunerITF: read busy (overflow)"); 1391 + } 1392 + dib8000_write_word(state, 1985, (0<<6) | (serpar_num&0x3f)); 1393 + 1394 + i = 1000; 1395 + while (n_empty == 1 && i) { 1396 + n_empty = dib8000_read_word(state, 1984)&0x1; 1397 + i--; 1398 + if (i == 0) 1399 + dprintk("TunerITF: read busy (empty)"); 1400 + } 1401 + 1402 + read_word = dib8000_read_word(state, 1987); 1403 + msg[1].buf[0] = (read_word >> 8) & 0xff; 1404 + msg[1].buf[1] = (read_word) & 0xff; 1405 + 1406 + return num; 1407 + } 1408 + 1409 + static int dib8096p_tuner_rw_serpar(struct i2c_adapter *i2c_adap, 1410 + struct i2c_msg msg[], int num) 1411 + { 1412 + if (map_addr_to_serpar_number(&msg[0]) == 0) { 1413 + if (num == 1) /* write */ 1414 + return dib8096p_tuner_write_serpar(i2c_adap, msg, 1); 1415 + else /* read */ 1416 + return dib8096p_tuner_read_serpar(i2c_adap, msg, 2); 1417 + } 1418 + return num; 1419 + } 1420 + 1421 + static int dib8096p_rw_on_apb(struct i2c_adapter *i2c_adap, 1422 + struct i2c_msg msg[], int num, u16 apb_address) 1423 + { 1424 + struct dib8000_state *state = i2c_get_adapdata(i2c_adap); 1425 + u16 word; 1426 + 1427 + if (num == 1) { /* write */ 1428 + dib8000_write_word(state, apb_address, 1429 + ((msg[0].buf[1] << 8) | (msg[0].buf[2]))); 1430 + } else { 1431 + word = dib8000_read_word(state, apb_address); 1432 + msg[1].buf[0] = (word >> 8) & 0xff; 1433 + msg[1].buf[1] = (word) & 0xff; 1434 + } 1435 + return num; 1436 + } 1437 + 1438 + static int dib8096p_tuner_xfer(struct i2c_adapter *i2c_adap, 1439 + struct i2c_msg msg[], int num) 1440 + { 1441 + struct dib8000_state *state = i2c_get_adapdata(i2c_adap); 1442 + u16 apb_address = 0, word; 1443 + int i = 0; 1444 + 1445 + switch (msg[0].buf[0]) { 1446 + case 0x12: 1447 + apb_address = 1920; 1448 + break; 1449 + case 0x14: 1450 + apb_address = 1921; 1451 + break; 1452 + case 0x24: 1453 + apb_address = 1922; 1454 + break; 1455 + case 0x1a: 1456 + apb_address = 1923; 1457 + break; 1458 + case 0x22: 1459 + apb_address = 1924; 1460 + break; 1461 + case 0x33: 1462 + apb_address = 1926; 1463 + break; 1464 + case 0x34: 1465 + apb_address = 1927; 1466 + break; 1467 + case 0x35: 1468 + apb_address = 1928; 1469 + break; 1470 + case 0x36: 1471 + apb_address = 1929; 1472 + break; 1473 + case 0x37: 1474 + apb_address = 1930; 1475 + break; 1476 + case 0x38: 1477 + apb_address = 1931; 1478 + break; 1479 + case 0x39: 1480 + apb_address = 1932; 1481 + break; 1482 + case 0x2a: 1483 + apb_address = 1935; 1484 + break; 1485 + case 0x2b: 1486 + apb_address = 1936; 1487 + break; 1488 + case 0x2c: 1489 + apb_address = 1937; 1490 + break; 1491 + case 0x2d: 1492 + apb_address = 1938; 1493 + break; 1494 + case 0x2e: 1495 + apb_address = 1939; 1496 + break; 1497 + case 0x2f: 1498 + apb_address = 1940; 1499 + break; 1500 + case 0x30: 1501 + apb_address = 1941; 1502 + break; 1503 + case 0x31: 1504 + apb_address = 1942; 1505 + break; 1506 + case 0x32: 1507 + apb_address = 1943; 1508 + break; 1509 + case 0x3e: 1510 + apb_address = 1944; 1511 + break; 1512 + case 0x3f: 1513 + apb_address = 1945; 1514 + break; 1515 + case 0x40: 1516 + apb_address = 1948; 1517 + break; 1518 + case 0x25: 1519 + apb_address = 936; 1520 + break; 1521 + case 0x26: 1522 + apb_address = 937; 1523 + break; 1524 + case 0x27: 1525 + apb_address = 938; 1526 + break; 1527 + case 0x28: 1528 + apb_address = 939; 1529 + break; 1530 + case 0x1d: 1531 + /* get sad sel request */ 1532 + i = ((dib8000_read_word(state, 921) >> 12)&0x3); 1533 + word = dib8000_read_word(state, 924+i); 1534 + msg[1].buf[0] = (word >> 8) & 0xff; 1535 + msg[1].buf[1] = (word) & 0xff; 1536 + return num; 1537 + case 0x1f: 1538 + if (num == 1) { /* write */ 1539 + word = (u16) ((msg[0].buf[1] << 8) | 1540 + msg[0].buf[2]); 1541 + /* in the VGAMODE Sel are located on bit 0/1 */ 1542 + word &= 0x3; 1543 + word = (dib8000_read_word(state, 921) & 1544 + ~(3<<12)) | (word<<12); 1545 + /* Set the proper input */ 1546 + dib8000_write_word(state, 921, word); 1547 + return num; 1548 + } 1549 + } 1550 + 1551 + if (apb_address != 0) /* R/W acces via APB */ 1552 + return dib8096p_rw_on_apb(i2c_adap, msg, num, apb_address); 1553 + else /* R/W access via SERPAR */ 1554 + return dib8096p_tuner_rw_serpar(i2c_adap, msg, num); 1555 + 1556 + return 0; 1557 + } 1558 + 1559 + static u32 dib8096p_i2c_func(struct i2c_adapter *adapter) 1560 + { 1561 + return I2C_FUNC_I2C; 1562 + } 1563 + 1564 + static struct i2c_algorithm dib8096p_tuner_xfer_algo = { 1565 + .master_xfer = dib8096p_tuner_xfer, 1566 + .functionality = dib8096p_i2c_func, 1567 + }; 1568 + 1569 + struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe) 1570 + { 1571 + struct dib8000_state *st = fe->demodulator_priv; 1572 + return &st->dib8096p_tuner_adap; 1573 + } 1574 + EXPORT_SYMBOL(dib8096p_get_i2c_tuner); 1575 + 1576 + int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff) 1577 + { 1578 + struct dib8000_state *state = fe->demodulator_priv; 1579 + u16 en_cur_state; 1580 + 1581 + dprintk("sleep dib8096p: %d", onoff); 1582 + 1583 + en_cur_state = dib8000_read_word(state, 1922); 1584 + 1585 + /* LNAs and MIX are ON and therefore it is a valid configuration */ 1586 + if (en_cur_state > 0xff) 1587 + state->tuner_enable = en_cur_state ; 1588 + 1589 + if (onoff) 1590 + en_cur_state &= 0x00ff; 1591 + else { 1592 + if (state->tuner_enable != 0) 1593 + en_cur_state = state->tuner_enable; 1594 + } 1595 + 1596 + dib8000_write_word(state, 1922, en_cur_state); 1597 + 1598 + return 0; 1599 + } 1600 + EXPORT_SYMBOL(dib8096p_tuner_sleep); 1601 + 1220 1602 static const s32 lut_1000ln_mant[] = 1221 1603 { 1222 1604 908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600 ··· 1815 1051 } 1816 1052 EXPORT_SYMBOL(dib8000_get_adc_power); 1817 1053 1054 + int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ) 1055 + { 1056 + struct dib8000_state *state = fe->demodulator_priv; 1057 + int val = 0; 1058 + 1059 + switch (IQ) { 1060 + case 1: 1061 + val = dib8000_read_word(state, 403); 1062 + break; 1063 + case 0: 1064 + val = dib8000_read_word(state, 404); 1065 + break; 1066 + } 1067 + if (val & 0x200) 1068 + val -= 1024; 1069 + 1070 + return val; 1071 + } 1072 + EXPORT_SYMBOL(dib8090p_get_dc_power); 1073 + 1818 1074 static void dib8000_update_timf(struct dib8000_state *state) 1819 1075 { 1820 1076 u32 timf = state->timf = dib8000_read32(state, 435); ··· 1843 1059 dib8000_write_word(state, 30, (u16) (timf & 0xffff)); 1844 1060 dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default); 1845 1061 } 1062 + 1063 + u32 dib8000_ctrl_timf(struct dvb_frontend *fe, uint8_t op, uint32_t timf) 1064 + { 1065 + struct dib8000_state *state = fe->demodulator_priv; 1066 + 1067 + switch (op) { 1068 + case DEMOD_TIMF_SET: 1069 + state->timf = timf; 1070 + break; 1071 + case DEMOD_TIMF_UPDATE: 1072 + dib8000_update_timf(state); 1073 + break; 1074 + case DEMOD_TIMF_GET: 1075 + break; 1076 + } 1077 + dib8000_set_bandwidth(state->fe[0], 6000); 1078 + 1079 + return state->timf; 1080 + } 1081 + EXPORT_SYMBOL(dib8000_ctrl_timf); 1846 1082 1847 1083 static const u16 adc_target_16dB[11] = { 1848 1084 (1 << 13) - 825 - 117, ··· 1889 1085 u16 coff_pow = 0x2800; 1890 1086 u16 init_prbs = 0xfff; 1891 1087 u16 ana_gain = 0; 1088 + 1089 + if (state->revision == 0x8090) 1090 + dib8000_init_sdram(state); 1892 1091 1893 1092 if (state->ber_monitored_layer != LAYER_ALL) 1894 1093 dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & 0x60) | state->ber_monitored_layer); ··· 2225 1418 dprintk("nbseg_diff = %X (%d)", seg_diff_mask, seg_diff_mask); 2226 1419 2227 1420 state->differential_constellation = (seg_diff_mask != 0); 2228 - dib8000_set_diversity_in(state->fe[0], state->diversity_onoff); 1421 + if (state->revision != 0x8090) 1422 + dib8000_set_diversity_in(state->fe[0], state->diversity_onoff); 1423 + else 1424 + dib8096p_set_diversity_in(state->fe[0], state->diversity_onoff); 2229 1425 2230 1426 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { 2231 1427 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1) ··· 2680 1870 { 2681 1871 struct dib8000_state *state = fe->demodulator_priv; 2682 1872 int ret = 0; 2683 - u16 value, mode = fft_to_mode(state); 1873 + u16 lock, value, mode = fft_to_mode(state); 2684 1874 2685 1875 // we are already tuned - just resuming from suspend 2686 1876 if (state == NULL) ··· 2734 1924 } 2735 1925 2736 1926 // we achieved a coff_cpil_lock - it's time to update the timf 2737 - if ((dib8000_read_word(state, 568) >> 11) & 0x1) 1927 + if (state->revision != 0x8090) 1928 + lock = dib8000_read_word(state, 568); 1929 + else 1930 + lock = dib8000_read_word(state, 570); 1931 + if ((lock >> 11) & 0x1) 2738 1932 dib8000_update_timf(state); 2739 1933 2740 1934 //now that tune is finished, lock0 should lock on fec_mpeg to output this lock on MP_LOCK. It's changed in autosearch start ··· 2760 1946 u8 index_frontend; 2761 1947 int ret; 2762 1948 2763 - dib8000_set_power_mode(state, DIB8000M_POWER_ALL); 1949 + dib8000_set_power_mode(state, DIB8000_POWER_ALL); 2764 1950 dib8000_set_adc_state(state, DIBX000_ADC_ON); 2765 1951 if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0) 2766 1952 dprintk("could not start Slow ADC"); 1953 + 1954 + if (state->revision != 0x8090) 1955 + dib8000_sad_calib(state); 2767 1956 2768 1957 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { 2769 1958 ret = state->fe[index_frontend]->ops.init(state->fe[index_frontend]); ··· 2789 1972 return ret; 2790 1973 } 2791 1974 2792 - dib8000_set_output_mode(fe, OUTMODE_HIGH_Z); 2793 - dib8000_set_power_mode(state, DIB8000M_POWER_INTERFACE_ONLY); 1975 + if (state->revision != 0x8090) 1976 + dib8000_set_output_mode(fe, OUTMODE_HIGH_Z); 1977 + dib8000_set_power_mode(state, DIB8000_POWER_INTERFACE_ONLY); 2794 1978 return dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(state, DIBX000_ADC_OFF); 2795 1979 } 2796 1980 ··· 2846 2028 2847 2029 fe->dtv_property_cache.isdbt_sb_mode = dib8000_read_word(state, 508) & 0x1; 2848 2030 2849 - val = dib8000_read_word(state, 570); 2031 + if (state->revision == 0x8090) 2032 + val = dib8000_read_word(state, 572); 2033 + else 2034 + val = dib8000_read_word(state, 570); 2850 2035 fe->dtv_property_cache.inversion = (val & 0x40) >> 6; 2851 2036 switch ((val & 0x30) >> 4) { 2852 2037 case 1: ··· 2979 2158 state->fe[index_frontend]->dtv_property_cache.delivery_system = SYS_ISDBT; 2980 2159 memcpy(&state->fe[index_frontend]->dtv_property_cache, &fe->dtv_property_cache, sizeof(struct dtv_frontend_properties)); 2981 2160 2982 - dib8000_set_output_mode(state->fe[index_frontend], OUTMODE_HIGH_Z); 2161 + if (state->revision != 0x8090) 2162 + dib8000_set_output_mode(state->fe[index_frontend], 2163 + OUTMODE_HIGH_Z); 2164 + else 2165 + dib8096p_set_output_mode(state->fe[index_frontend], 2166 + OUTMODE_HIGH_Z); 2983 2167 if (state->fe[index_frontend]->ops.tuner_ops.set_params) 2984 2168 state->fe[index_frontend]->ops.tuner_ops.set_params(state->fe[index_frontend], fep); 2985 2169 ··· 3095 2269 ret = dib8000_tune(state->fe[index_frontend]); 3096 2270 3097 2271 /* set output mode and diversity input */ 3098 - dib8000_set_output_mode(state->fe[0], state->cfg.output_mode); 3099 - for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { 3100 - dib8000_set_output_mode(state->fe[index_frontend], OUTMODE_DIVERSITY); 3101 - dib8000_set_diversity_in(state->fe[index_frontend-1], 1); 3102 - } 2272 + if (state->revision != 0x8090) { 2273 + dib8000_set_output_mode(state->fe[0], state->cfg.output_mode); 2274 + for (index_frontend = 1; 2275 + (index_frontend < MAX_NUMBER_OF_FRONTENDS) && 2276 + (state->fe[index_frontend] != NULL); 2277 + index_frontend++) { 2278 + dib8000_set_output_mode(state->fe[index_frontend], 2279 + OUTMODE_DIVERSITY); 2280 + dib8000_set_diversity_in(state->fe[index_frontend-1], 1); 2281 + } 3103 2282 3104 - /* turn off the diversity of the last chip */ 3105 - dib8000_set_diversity_in(state->fe[index_frontend-1], 0); 2283 + /* turn off the diversity of the last chip */ 2284 + dib8000_set_diversity_in(state->fe[index_frontend-1], 0); 2285 + } else { 2286 + dib8096p_set_output_mode(state->fe[0], state->cfg.output_mode); 2287 + if (state->cfg.enMpegOutput == 0) { 2288 + dib8096p_setDibTxMux(state, MPEG_ON_DIBTX); 2289 + dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS); 2290 + } 2291 + for (index_frontend = 1; 2292 + (index_frontend < MAX_NUMBER_OF_FRONTENDS) && 2293 + (state->fe[index_frontend] != NULL); 2294 + index_frontend++) { 2295 + dib8096p_set_output_mode(state->fe[index_frontend], 2296 + OUTMODE_DIVERSITY); 2297 + dib8096p_set_diversity_in(state->fe[index_frontend-1], 1); 2298 + } 2299 + 2300 + /* turn off the diversity of the last chip */ 2301 + dib8096p_set_diversity_in(state->fe[index_frontend-1], 0); 2302 + } 3106 2303 3107 2304 return ret; 3108 2305 } ··· 3134 2285 { 3135 2286 struct dib8000_state *state = fe->demodulator_priv; 3136 2287 2288 + if (state->revision == 0x8090) 2289 + return dib8000_read_word(state, 570); 3137 2290 return dib8000_read_word(state, 568); 3138 2291 } 3139 2292 3140 2293 static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat) 3141 2294 { 3142 2295 struct dib8000_state *state = fe->demodulator_priv; 3143 - u16 lock_slave = 0, lock = dib8000_read_word(state, 568); 2296 + u16 lock_slave = 0, lock; 3144 2297 u8 index_frontend; 2298 + 2299 + if (state->revision == 0x8090) 2300 + lock = dib8000_read_word(state, 570); 2301 + else 2302 + lock = dib8000_read_word(state, 568); 3145 2303 3146 2304 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) 3147 2305 lock_slave |= dib8000_read_lock(state->fe[index_frontend]); ··· 3187 2331 static int dib8000_read_ber(struct dvb_frontend *fe, u32 * ber) 3188 2332 { 3189 2333 struct dib8000_state *state = fe->demodulator_priv; 3190 - *ber = (dib8000_read_word(state, 560) << 16) | dib8000_read_word(state, 561); // 13 segments 2334 + 2335 + /* 13 segments */ 2336 + if (state->revision == 0x8090) 2337 + *ber = (dib8000_read_word(state, 562) << 16) | 2338 + dib8000_read_word(state, 563); 2339 + else 2340 + *ber = (dib8000_read_word(state, 560) << 16) | 2341 + dib8000_read_word(state, 561); 3191 2342 return 0; 3192 2343 } 3193 2344 3194 2345 static int dib8000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc) 3195 2346 { 3196 2347 struct dib8000_state *state = fe->demodulator_priv; 3197 - *unc = dib8000_read_word(state, 565); // packet error on 13 seg 2348 + 2349 + /* packet error on 13 seg */ 2350 + if (state->revision == 0x8090) 2351 + *unc = dib8000_read_word(state, 567); 2352 + else 2353 + *unc = dib8000_read_word(state, 565); 3198 2354 return 0; 3199 2355 } 3200 2356 ··· 3239 2371 u32 n, s, exp; 3240 2372 u16 val; 3241 2373 3242 - val = dib8000_read_word(state, 542); 2374 + if (state->revision != 0x8090) 2375 + val = dib8000_read_word(state, 542); 2376 + else 2377 + val = dib8000_read_word(state, 544); 3243 2378 n = (val >> 6) & 0xff; 3244 2379 exp = (val & 0x3f); 3245 2380 if ((exp & 0x20) != 0) 3246 2381 exp -= 0x40; 3247 2382 n <<= exp+16; 3248 2383 3249 - val = dib8000_read_word(state, 543); 2384 + if (state->revision != 0x8090) 2385 + val = dib8000_read_word(state, 543); 2386 + else 2387 + val = dib8000_read_word(state, 545); 3250 2388 s = (val >> 6) & 0xff; 3251 2389 exp = (val & 0x3f); 3252 2390 if ((exp & 0x20) != 0) ··· 3333 2459 EXPORT_SYMBOL(dib8000_get_slave_frontend); 3334 2460 3335 2461 3336 - int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr) 2462 + int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, 2463 + u8 default_addr, u8 first_addr, u8 is_dib8096p) 3337 2464 { 3338 2465 int k = 0, ret = 0; 3339 2466 u8 new_addr = 0; ··· 3364 2489 new_addr = first_addr + (k << 1); 3365 2490 3366 2491 client.addr = new_addr; 3367 - dib8000_i2c_write16(&client, 1287, 0x0003); /* sram lead in, rdy */ 3368 - if (dib8000_identify(&client) == 0) { 2492 + if (!is_dib8096p) 3369 2493 dib8000_i2c_write16(&client, 1287, 0x0003); /* sram lead in, rdy */ 2494 + if (dib8000_identify(&client) == 0) { 2495 + /* sram lead in, rdy */ 2496 + if (!is_dib8096p) 2497 + dib8000_i2c_write16(&client, 1287, 0x0003); 3370 2498 client.addr = default_addr; 3371 2499 if (dib8000_identify(&client) == 0) { 3372 2500 dprintk("#%d: not identified", k); ··· 3428 2550 dvb_frontend_detach(st->fe[index_frontend]); 3429 2551 3430 2552 dibx000_exit_i2c_master(&st->i2c_master); 2553 + i2c_del_adapter(&st->dib8096p_tuner_adap); 3431 2554 kfree(st->fe[0]); 3432 2555 kfree(st); 3433 2556 } ··· 3530 2651 goto error; 3531 2652 3532 2653 dibx000_init_i2c_master(&state->i2c_master, DIB8000, state->i2c.adap, state->i2c.addr); 2654 + 2655 + /* init 8096p tuner adapter */ 2656 + strncpy(state->dib8096p_tuner_adap.name, "DiB8096P tuner interface", 2657 + sizeof(state->dib8096p_tuner_adap.name)); 2658 + state->dib8096p_tuner_adap.algo = &dib8096p_tuner_xfer_algo; 2659 + state->dib8096p_tuner_adap.algo_data = NULL; 2660 + state->dib8096p_tuner_adap.dev.parent = state->i2c.adap->dev.parent; 2661 + i2c_set_adapdata(&state->dib8096p_tuner_adap, state); 2662 + i2c_add_adapter(&state->dib8096p_tuner_adap); 3533 2663 3534 2664 dib8000_reset(fe); 3535 2665
+40 -2
drivers/media/dvb/frontends/dib8000.h
··· 32 32 u8 div_cfg; 33 33 u8 output_mode; 34 34 u8 refclksel; 35 + u8 enMpegOutput:1; 35 36 }; 36 37 37 38 #define DEFAULT_DIB8000_I2C_ADDRESS 18 ··· 41 40 extern struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg); 42 41 extern struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int); 43 42 44 - extern int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr); 43 + extern int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, 44 + u8 default_addr, u8 first_addr, u8 is_dib8096p); 45 45 46 46 extern int dib8000_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val); 47 47 extern int dib8000_set_wbd_ref(struct dvb_frontend *, u16 value); ··· 52 50 extern enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe); 53 51 extern void dib8000_pwm_agc_reset(struct dvb_frontend *fe); 54 52 extern s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode); 53 + extern struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe); 54 + extern int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff); 55 + extern int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ); 56 + extern u32 dib8000_ctrl_timf(struct dvb_frontend *fe, 57 + uint8_t op, uint32_t timf); 58 + extern int dib8000_update_pll(struct dvb_frontend *fe, 59 + struct dibx000_bandwidth_config *pll); 55 60 extern int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave); 56 61 extern int dib8000_remove_slave_frontend(struct dvb_frontend *fe); 57 62 extern struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index); ··· 75 66 return NULL; 76 67 } 77 68 78 - static inline int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr) 69 + static inline int dib8000_i2c_enumeration(struct i2c_adapter *host, 70 + int no_of_demods, u8 default_addr, u8 first_addr, 71 + u8 is_dib8096p) 79 72 { 80 73 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 81 74 return -ENODEV; ··· 120 109 { 121 110 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 122 111 } 112 + static inline struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe) 113 + { 114 + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 115 + return NULL; 116 + } 117 + static inline int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff) 118 + { 119 + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 120 + return 0; 121 + } 123 122 static inline s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode) 124 123 { 125 124 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 126 125 return 0; 126 + } 127 + static inline int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ) 128 + { 129 + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 130 + return 0; 131 + } 132 + static inline u32 dib8000_ctrl_timf(struct dvb_frontend *fe, 133 + uint8_t op, uint32_t timf) 134 + { 135 + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 136 + return 0; 137 + } 138 + static inline int dib8000_update_pll(struct dvb_frontend *fe, 139 + struct dibx000_bandwidth_config *pll) 140 + { 141 + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 142 + return -ENODEV; 127 143 } 128 144 static inline int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave) 129 145 {
+7
drivers/media/dvb/frontends/dibx000_common.h
··· 276 276 #define DEMOD_TIMF_GET 0x01 277 277 #define DEMOD_TIMF_UPDATE 0x02 278 278 279 + #define MPEG_ON_DIBTX 1 280 + #define DIV_ON_DIBTX 2 281 + #define ADC_ON_DIBTX 3 282 + #define DEMOUT_ON_HOSTBUS 4 283 + #define DIBTX_ON_HOSTBUS 5 284 + #define MPEG_ON_HOSTBUS 6 285 + 279 286 #endif