summaryrefslogtreecommitdiffstats
path: root/drivers/media/pci/bt8xx/bttv-cards.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/pci/bt8xx/bttv-cards.c')
-rw-r--r--drivers/media/pci/bt8xx/bttv-cards.c110
1 files changed, 110 insertions, 0 deletions
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)
@@ -4185,6 +4205,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 */
/*
* Copyright (c) 1999 Csaba Halasz <qgehali@uni-miskolc.hu>
OpenPOWER on IntegriCloud