diff --git a/drivers/media/pci/bt8xx/bttv-cards.c b/drivers/media/pci/bt8xx/bttv-cards.c index d06963b3dcf3..d8ec583c154c 100644 --- a/drivers/media/pci/bt8xx/bttv-cards.c +++ b/drivers/media/pci/bt8xx/bttv-cards.c @@ -52,6 +52,7 @@ static void osprey_eeprom(struct bttv *btv, const u8 ee[256]); static void modtec_eeprom(struct bttv *btv); static void init_PXC200(struct bttv *btv); static void init_RTV24(struct bttv *btv); +static void init_PCI8604PW(struct bttv *btv); static void rv605_muxsel(struct bttv *btv, unsigned int input); static void eagle_muxsel(struct bttv *btv, unsigned int input); @@ -2871,6 +2872,22 @@ struct tvcard bttv_tvcards[] = { .has_remote = 1, .has_radio = 1, }, + /* ---- card 0xa6---------------------------------- */ + [BTTV_BOARD_PCI_8604PW] = { + /* PCI-8604PW with special unlock sequence */ + .name = "PCI-8604PW", + .video_inputs = 2, + /* .audio_inputs= 0, */ + .svhs = NO_SVHS, + /* The second input is available on CN4, if populated. + * The other 5x2 header (CN2?) connects to the same inputs + * as the on-board BNCs */ + .muxsel = MUXSEL(2, 3), + .tuner_type = TUNER_ABSENT, + .no_msp34xx = 1, + .no_tda7432 = 1, + .pll = PLL_35, + }, }; static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); @@ -3305,6 +3322,9 @@ void bttv_init_card1(struct bttv *btv) case BTTV_BOARD_ADLINK_RTV24: init_RTV24( btv ); break; + case BTTV_BOARD_PCI_8604PW: + init_PCI8604PW(btv); + break; } if (!bttv_tvcards[btv->c.type].has_dvb) @@ -4184,6 +4204,96 @@ init_RTV24 (struct bttv *btv) +/* ----------------------------------------------------------------------- */ +/* + * The PCI-8604PW contains a CPLD, probably an ispMACH 4A, that filters + * the PCI REQ signals comming from the four BT878 chips. After power + * up, the CPLD does not forward requests to the bus, which prevents + * the BT878 from fetching RISC instructions from memory. While the + * CPLD is connected to most of the GPIOs of PCI device 0xD, only + * five appear to play a role in unlocking the REQ signal. The following + * sequence has been determined by trial and error without access to the + * original driver. + * + * Eight GPIOs of device 0xC are provided on connector CN4 (4 in, 4 out). + * Devices 0xE and 0xF do not appear to have anything connected to their + * GPIOs. + * + * The correct GPIO_OUT_EN value might have some more bits set. It should + * be possible to derive it from a boundary scan of the CPLD. Its JTAG + * pins are routed to test points. + * + */ +/* ----------------------------------------------------------------------- */ +static void +init_PCI8604PW(struct bttv *btv) +{ + int state; + + if ((PCI_SLOT(btv->c.pci->devfn) & ~3) != 0xC) { + pr_warn("This is not a PCI-8604PW\n"); + return; + } + + if (PCI_SLOT(btv->c.pci->devfn) != 0xD) + return; + + btwrite(0x080002, BT848_GPIO_OUT_EN); + + state = (btread(BT848_GPIO_DATA) >> 21) & 7; + + for (;;) { + switch (state) { + case 1: + case 5: + case 6: + case 4: + pr_debug("PCI-8604PW in state %i, toggling pin\n", + state); + btwrite(0x080000, BT848_GPIO_DATA); + msleep(1); + btwrite(0x000000, BT848_GPIO_DATA); + msleep(1); + break; + case 7: + pr_info("PCI-8604PW unlocked\n"); + return; + case 0: + /* FIXME: If we are in state 7 and toggle GPIO[19] one + more time, the CPLD goes into state 0, where PCI bus + mastering is inhibited again. We have not managed to + get out of that state. */ + + pr_err("PCI-8604PW locked until reset\n"); + return; + default: + pr_err("PCI-8604PW in unknown state %i\n", state); + return; + } + + state = (state << 4) | ((btread(BT848_GPIO_DATA) >> 21) & 7); + + switch (state) { + case 0x15: + case 0x56: + case 0x64: + case 0x47: + /* The transition from state 7 to state 0 is, as explained + above, valid but undesired and with this code impossible + as we exit as soon as we are in state 7. + case 0x70: */ + break; + default: + pr_err("PCI-8604PW invalid transition %i -> %i\n", + state >> 4, state & 7); + return; + } + state &= 7; + } +} + + + /* ----------------------------------------------------------------------- */ /* Miro Pro radio stuff -- the tea5757 is connected to some GPIO ports */ /* diff --git a/drivers/media/pci/bt8xx/bttv.h b/drivers/media/pci/bt8xx/bttv.h index bb5da349a46e..f08126244662 100644 --- a/drivers/media/pci/bt8xx/bttv.h +++ b/drivers/media/pci/bt8xx/bttv.h @@ -189,6 +189,7 @@ #define BTTV_BOARD_BT848_CAP_14 0xa3 #define BTTV_BOARD_CYBERVISION_CV06 0xa4 #define BTTV_BOARD_KWORLD_VSTREAM_XPERT 0xa5 +#define BTTV_BOARD_PCI_8604PW 0xa6 /* more card-specific defines */ #define PT2254_L_CHANNEL 0x10