|
@@ -52,6 +52,7 @@ static void osprey_eeprom(struct bttv *btv, const u8 ee[256]);
|
|
static void modtec_eeprom(struct bttv *btv);
|
|
static void modtec_eeprom(struct bttv *btv);
|
|
static void init_PXC200(struct bttv *btv);
|
|
static void init_PXC200(struct bttv *btv);
|
|
static void init_RTV24(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 rv605_muxsel(struct bttv *btv, unsigned int input);
|
|
static void eagle_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_remote = 1,
|
|
.has_radio = 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);
|
|
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:
|
|
case BTTV_BOARD_ADLINK_RTV24:
|
|
init_RTV24( btv );
|
|
init_RTV24( btv );
|
|
break;
|
|
break;
|
|
|
|
+ case BTTV_BOARD_PCI_8604PW:
|
|
|
|
+ init_PCI8604PW(btv);
|
|
|
|
+ break;
|
|
|
|
|
|
}
|
|
}
|
|
if (!bttv_tvcards[btv->c.type].has_dvb)
|
|
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 */
|
|
/* Miro Pro radio stuff -- the tea5757 is connected to some GPIO ports */
|
|
/*
|
|
/*
|