summaryrefslogtreecommitdiff
path: root/sys/dev/pci/brooktree848.c
diff options
context:
space:
mode:
authorJason Downs <downsj@cvs.openbsd.org>1998-10-10 06:39:24 +0000
committerJason Downs <downsj@cvs.openbsd.org>1998-10-10 06:39:24 +0000
commita3e9b650fba5e1621d70f2530c9b9444aa6582e4 (patch)
tree1d71d9e9a3be6c328a4d46fbb858a3a1339d74b4 /sys/dev/pci/brooktree848.c
parentc8a4c001ff4d0626f71da4c18c58b0a1f92b646a (diff)
Sync with FreeBSD; add support for bt878/879, more cards, more tuners...
Diffstat (limited to 'sys/dev/pci/brooktree848.c')
-rw-r--r--sys/dev/pci/brooktree848.c1280
1 files changed, 923 insertions, 357 deletions
diff --git a/sys/dev/pci/brooktree848.c b/sys/dev/pci/brooktree848.c
index 5d091170a6e..b94ceea25ae 100644
--- a/sys/dev/pci/brooktree848.c
+++ b/sys/dev/pci/brooktree848.c
@@ -1,4 +1,6 @@
-/* BT848 1.30 Driver for Brooktree's Bt848 based cards.
+/* $OpenBSD: brooktree848.c,v 1.4 1998/10/10 06:39:23 downsj Exp $ */
+/* $FreeBSD: brooktree848.c,v 1.56 1998/10/01 09:35:48 sos Exp $ */
+/* BT848 Driver for Brooktree's Bt848 based cards.
The Brooktree BT848 Driver driver is based upon Mark Tinguely and
Jim Lowe's driver for the Matrox Meteor PCI card . The
Philips SAA 7116 and SAA 7196 are very different chipsets than
@@ -230,6 +232,91 @@
format change.
1.30 Bring back Frank Nobis <fn@Radio-do.de>'s opt_bktr.h
+1.31 Randall Hopper <rhh@ct.picker.com>
+ submitted ioctl to clear the video buffer
+ prior to starting video capture
+ Amancio : clean up yuv12 so that it does not
+ affect rgb capture. Basically, fxtv after
+ capturing in yuv12 mode , switching to rgb
+ would cause the video capture to be too bright.
+1.32 disable inverse gamma function for rgb and yuv
+ capture. fixed meteor brightness ioctl it now
+ converts the brightness value from unsigned to
+ signed.
+1.33 added sysctl: hw.bt848.tuner, hw.bt848.reverse_mute,
+ hw.bt848.card
+ card takes a value from 0 to bt848_max_card
+ tuner takes a value from 0 to bt848_max_tuner
+ reverse_mute : 0 no effect, 1 reverse tuner
+ mute function some tuners are wired reversed :(
+1.34 reverse mute function for ims turbo card
+
+1.35 Roger Hardiman <roger@cs.strath.ac.uk>
+ options BROOKTREE_SYSTEM_DEFAULT=BROOKTREE_PAL
+ in the kernel config file makes the driver's
+ video_open() function select PAL rather than NTSC.
+ This fixed all the hangs on my Dual Crystal card
+ when using a PAL video signal. As a result, you
+ can loose the tsleep (of 2 seconds - now 0.25!!)
+ which I previously added. (Unless someone else
+ wanted the 0.25 second tsleep).
+
+1.36 added bt848.format sysctl variable.
+ 1 denotes NTSC , 0 denotes PAL
+
+1.37 added support for Bt878 and improved Hauppauge's
+ bt848 tuner recognition
+1.38 Further improvements on Hauppauge's rely on
+ eeprom[9] to determine the tuner type 8)
+
+ AVerMedia card type added <sos@freebsd.org>
+
+1.39 08/05/98 Roger Hardiman <roger@cs.strath.ac.uk>
+ Updated Hauppauge detection code for Tuner ID 0x0a
+ for newer NTSC WinCastTV 404 with Bt878 chipset.
+ Tidied up PAL default in video_open()
+
+1.49 10 August 1998 Roger Hardiman <roger@cs.strath.ac.uk>
+ Added Capture Area ioctl - BT848[SG]CAPAREA.
+ Normally the full 640x480 (768x576 PAL) image
+ is grabbed. This ioctl allows a smaller area
+ from anywhere within the video image to be
+ grabbed, eg a 400x300 image from (50,10).
+ See restrictions in BT848SCAPAREA.
+
+1.50 31 August 1998 Roger Hardiman <roger@cs.strath.ac.uk>
+ Renamed BT848[SG]CAPAREA to BT848_[SG]CAPAREA.
+ Added PR kern/7177 for SECAM Video Highway Xtreme
+ with single crystal PLL configuration
+ submitted by Vsevolod Lobko <seva@alex-ua.com>.
+ In kernel configuration file add
+ options OVERRIDE_CARD=2
+ options OVERRIDE_TUNER=11
+ options BKTR_USE_PLL
+
+1.51 31 August 1998 Roger Hardiman <roger@cs.strath.ac.uk>
+ Fixed bug in Miro Tuner detection. Missing Goto.
+ Removed Hauppauge EEPROM 0x10 detection as I think
+ 0x10 should be a PAL tuner, not NTSC.
+ Reinstated some Tuner Guesswork code from 1.27
+
+1.52 3 Sep 1998 Roger Hardiman <roger@cs.strath.ac.uk>
+ Submitted patch by Vsevolod Lobko <seva@alex-ua.com>
+ to correct SECAM B-Delay and add XUSSR channel set.
+
+1.53 9 Sep 1998 Roger Hardiman <roger@cs.strath.ac.uk>
+ Changed METEORSINPUT for Hauppauge cards with bt878.
+ Submitted by Fred Templin <templin@erg.sri.com>
+ Also fixed video_open defines and 878 support.
+
+1.54 18 Sep 1998 Roger Hardiman <roger@cs.strath.ac.uk>
+ Changed tuner code to autodetect tuner i2c address.
+ Addresses were incorrectly hardcoded.
+
+1.55 21 Sep 1998 Roger Hardiman <roger@cs.strath.ac.uk>
+ Hauppauge Tech Support confirmed all Hauppauge 878
+ PAL/SECAM boards will use PLL mode.
+ Added to card probe. Thanks to Ken and Fred.
*/
#if !defined(__NetBSD__) && !defined(__OpenBSD__)
@@ -239,6 +326,7 @@
#ifdef __FreeBSD__
#include "bktr.h"
+#include "opt_bktr.h"
#include "opt_devfs.h"
#include "pci.h"
#endif /* __FreeBSD__ */
@@ -273,8 +361,19 @@
#include <machine/ioctl_meteor.h>
#include <machine/ioctl_bt848.h> /* extensions to ioctl_meteor.h */
#include <pci/brktree_reg.h>
+#include <sys/sysctl.h>
+static int bt848_card = -1;
+static int bt848_tuner = -1;
+static int bt848_reverse_mute = -1;
+static int bt848_format = -1;
+
+SYSCTL_NODE(_hw, OID_AUTO, bt848, CTLFLAG_RW, 0, "Bt848 Driver mgmt");
+SYSCTL_INT(_hw_bt848, OID_AUTO, card, CTLFLAG_RW, &bt848_card, -1, "");
+SYSCTL_INT(_hw_bt848, OID_AUTO, tuner, CTLFLAG_RW, &bt848_tuner, -1, "");
+SYSCTL_INT(_hw_bt848, OID_AUTO, reverse_mute, CTLFLAG_RW, &bt848_reverse_mute, -1, "");
+SYSCTL_INT(_hw_bt848, OID_AUTO, format, CTLFLAG_RW, &bt848_format, -1, "");
-typedef int ioctl_cmd_t;
+typedef u_long ioctl_cmd_t;
#endif /* __FreeBSD__ */
#ifdef __bsdi__
@@ -315,8 +414,15 @@ typedef u_long ioctl_cmd_t;
typedef int ioctl_cmd_t;
+typedef unsigned long uintptr_t;
+
static int bootverbose = 1;
+static int bt848_card = -1;
+static int bt848_tuner = -1;
+static int bt848_reverse_mute = -1;
+static int bt848_format = -1;
+
#define BKTR_DEBUG
#ifdef BKTR_DEBUG
int bktr_debug = 0;
@@ -430,8 +536,12 @@ bktr_pci_match(pci_devaddr_t *pa)
id = pci_inl(pa, PCI_VENDOR_ID);
- if (id == BROOKTREE_848_ID || id == BROOKTREE_849_ID ) {
- return 1;
+ switch (id) {
+ BROOKTREE_848_ID:
+ BROOKTREE_849_ID:
+ BROOKTREE_878_ID:
+ BROOKTREE_879_ID:
+ return 1;
}
aprint_debug("bktr_pci_match got %x\n", id);
return 0;
@@ -537,7 +647,9 @@ int bktr_probe(parent, match, aux)
if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROOKTREE &&
(PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROOKTREE_BT848 ||
- PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROOKTREE_BT849))
+ PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROOKTREE_BT849 ||
+ PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROOKTREE_BT878 ||
+ PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROOKTREE_BT879))
return 1;
return 0;
@@ -571,7 +683,7 @@ static struct format_params format_params[] = {
/* # define BT848_IFORM_F_PALN (0x5) */
{ 625, 32, 576, 1135, 186, 922, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT1 },
/* # define BT848_IFORM_F_SECAM (0x6) */
- { 625, 32, 576, 1135, 186, 922, 768, 944, 25, 0x7f, 0x00, BT848_IFORM_X_XT1 },
+ { 625, 32, 576, 1135, 186, 922, 768, 944, 25, 0x7f, 0xa0, BT848_IFORM_X_XT1 },
/* # define BT848_IFORM_F_RSVD (0x7) - ???? */
{ 625, 32, 576, 1135, 186, 922, 768, 944, 25, 0x7f, 0x72, BT848_IFORM_X_XT0 },
};
@@ -675,6 +787,10 @@ static struct {
#define PHILIPS_FR1236_NTSC_WADDR 0xc2
#define PHILIPS_FR1236_NTSC_RADDR 0xc3
+/* PLL on a the Philips FR1236MK2 tuner */
+#define PHILIPS_FR1236_SECAM_WADDR 0xc0
+#define PHILIPS_FR1236_SECAM_RADDR 0xc1
+
/* PLL on a the Philips FR1216MK2 tuner,
yes, the european version of the tuner is 1216 */
#define PHILIPS_FR1216_PAL_WADDR 0xc2
@@ -757,6 +873,291 @@ static struct {
/* the GPIO bits that control the audio MUXes */
#define GPIO_AUDIOMUX_BITS 0x0f
+/*
+ * the data for each type of tuner
+ *
+ * if probeCard() fails to detect the proper tuner on boot you can
+ * override it by setting the following define to the tuner present:
+ *
+#define OVERRIDE_TUNER <tuner type>
+ *
+ * where <tuner type> is one of the following tuner defines.
+ */
+
+/* indexes into tuners[] */
+#define NO_TUNER 0
+#define TEMIC_NTSC 1
+#define TEMIC_PAL 2
+#define TEMIC_SECAM 3
+#define PHILIPS_NTSC 4
+#define PHILIPS_PAL 5
+#define PHILIPS_SECAM 6
+#define TEMIC_PALI 7
+#define PHILIPS_PALI 8
+#define PHILIPS_FR1236_NTSC 9
+#define PHILIPS_FR1216_PAL 10
+#define PHILIPS_FR1236_SECAM 11
+#define Bt848_MAX_TUNER 12
+
+/* XXX FIXME: this list is incomplete */
+
+/* input types */
+#define TTYPE_XXX 0
+#define TTYPE_NTSC 1
+#define TTYPE_NTSC_J 2
+#define TTYPE_PAL 3
+#define TTYPE_PAL_M 4
+#define TTYPE_PAL_N 5
+#define TTYPE_SECAM 6
+
+/**
+struct TUNER {
+ char* name;
+ u_char type;
+ u_char pllAddr;
+ u_char pllControl;
+ u_char bandLimits[ 2 ];
+ u_char bandAddrs[ 3 ];
+};
+ */
+static const struct TUNER tuners[] = {
+/* XXX FIXME: fill in the band-switch crosspoints */
+ /* NO_TUNER */
+ { "<none>", /* the 'name' */
+ TTYPE_XXX, /* input type */
+ 0x00, /* PLL write address */
+ { 0x00, /* control byte for PLL */
+ 0x00,
+ 0x00,
+ 0x00 },
+ { 0x00, 0x00 }, /* band-switch crosspoints */
+ { 0x00, 0x00, 0x00,0x00} }, /* the band-switch values */
+
+ /* TEMIC_NTSC */
+ { "Temic NTSC", /* the 'name' */
+ TTYPE_NTSC, /* input type */
+ TEMIC_NTSC_WADDR, /* PLL write address */
+ { TSA552x_SCONTROL, /* control byte for PLL */
+ TSA552x_SCONTROL,
+ TSA552x_SCONTROL,
+ 0x00 },
+ { 0x00, 0x00 }, /* band-switch crosspoints */
+ { 0x02, 0x04, 0x01, 0x00 } }, /* the band-switch values */
+
+ /* TEMIC_PAL */
+ { "Temic PAL", /* the 'name' */
+ TTYPE_PAL, /* input type */
+ TEMIC_PALI_WADDR, /* PLL write address */
+ { TSA552x_SCONTROL, /* control byte for PLL */
+ TSA552x_SCONTROL,
+ TSA552x_SCONTROL,
+ 0x00 },
+ { 0x00, 0x00 }, /* band-switch crosspoints */
+ { 0x02, 0x04, 0x01, 0x00 } }, /* the band-switch values */
+
+ /* TEMIC_SECAM */
+ { "Temic SECAM", /* the 'name' */
+ TTYPE_SECAM, /* input type */
+ 0x00, /* PLL write address */
+ { TSA552x_SCONTROL, /* control byte for PLL */
+ TSA552x_SCONTROL,
+ TSA552x_SCONTROL,
+ 0x00 },
+ { 0x00, 0x00 }, /* band-switch crosspoints */
+ { 0x02, 0x04, 0x01,0x00 } }, /* the band-switch values */
+
+ /* PHILIPS_NTSC */
+ { "Philips NTSC", /* the 'name' */
+ TTYPE_NTSC, /* input type */
+ PHILIPS_NTSC_WADDR, /* PLL write address */
+ { TSA552x_SCONTROL, /* control byte for PLL */
+ TSA552x_SCONTROL,
+ TSA552x_SCONTROL,
+ 0x00 },
+ { 0x00, 0x00 }, /* band-switch crosspoints */
+ { 0xa0, 0x90, 0x30, 0x00 } }, /* the band-switch values */
+
+ /* PHILIPS_PAL */
+ { "Philips PAL", /* the 'name' */
+ TTYPE_PAL, /* input type */
+ PHILIPS_PAL_WADDR, /* PLL write address */
+ { TSA552x_FCONTROL, /* control byte for PLL */
+ TSA552x_FCONTROL,
+ TSA552x_FCONTROL,
+ TSA552x_RADIO },
+ { 0x00, 0x00 }, /* band-switch crosspoints */
+ { 0xa0, 0x90, 0x30, 0xa4 } }, /* the band-switch values */
+
+ /* PHILIPS_SECAM */
+ { "Philips SECAM", /* the 'name' */
+ TTYPE_SECAM, /* input type */
+ 0x00, /* PLL write address */
+ { TSA552x_SCONTROL, /* control byte for PLL */
+ TSA552x_SCONTROL,
+ TSA552x_SCONTROL,
+ TSA552x_RADIO },
+ { 0x00, 0x00 }, /* band-switch crosspoints */
+ { 0xa0, 0x90, 0x30,0xa4 } }, /* the band-switch values */
+
+ /* TEMIC_PAL I */
+ { "Temic PAL I", /* the 'name' */
+ TTYPE_PAL, /* input type */
+ TEMIC_PALI_WADDR, /* PLL write address */
+ { TSA552x_SCONTROL, /* control byte for PLL */
+ TSA552x_SCONTROL,
+ TSA552x_SCONTROL,
+ 0x00 },
+ { 0x00, 0x00 }, /* band-switch crosspoints */
+ { 0x02, 0x04, 0x01,0x00 } }, /* the band-switch values */
+
+ /* PHILIPS_PAL */
+ { "Philips PAL I", /* the 'name' */
+ TTYPE_PAL, /* input type */
+ TEMIC_PALI_WADDR, /* PLL write address */
+ { TSA552x_SCONTROL, /* control byte for PLL */
+ TSA552x_SCONTROL,
+ TSA552x_SCONTROL,
+ 0x00 },
+ { 0x00, 0x00 }, /* band-switch crosspoints */
+ { 0xa0, 0x90, 0x30,0x00 } }, /* the band-switch values */
+
+ /* PHILIPS_FR1236_NTSC */
+ { "Philips FR1236 NTSC FM", /* the 'name' */
+ TTYPE_NTSC, /* input type */
+ PHILIPS_FR1236_NTSC_WADDR, /* PLL write address */
+ { TSA552x_SCONTROL, /* control byte for PLL */
+ TSA552x_SCONTROL,
+ TSA552x_SCONTROL,
+ TSA552x_RADIO },
+ { 0x00, 0x00 }, /* band-switch crosspoints */
+ { 0xa0, 0x90, 0x30,0xa4 } }, /* the band-switch values */
+
+ /* PHILIPS_FR1216_PAL */
+ { "Philips FR1216 PAL" , /* the 'name' */
+ TTYPE_PAL, /* input type */
+ PHILIPS_FR1216_PAL_WADDR, /* PLL write address */
+ { TSA552x_FCONTROL, /* control byte for PLL */
+ TSA552x_FCONTROL,
+ TSA552x_FCONTROL,
+ TSA552x_RADIO },
+ { 0x00, 0x00 }, /* band-switch crosspoints */
+ { 0xa0, 0x90, 0x30, 0xa4 } }, /* the band-switch values */
+
+ /* PHILIPS_FR1236_SECAM */
+ { "Philips FR1236 SECAM FM", /* the 'name' */
+ TTYPE_SECAM, /* input type */
+ PHILIPS_FR1236_SECAM_WADDR, /* PLL write address */
+ { TSA552x_FCONTROL, /* control byte for PLL */
+ TSA552x_FCONTROL,
+ TSA552x_FCONTROL,
+ TSA552x_RADIO },
+ { 0x00, 0x00 }, /* band-switch crosspoints */
+ { 0xa0, 0x90, 0x30, 0xa4 } }, /* the band-switch values */
+};
+
+/******************************************************************************
+ * card probe
+ */
+
+
+/*
+ * the recognized cards, used as indexes of several tables.
+ *
+ * if probeCard() fails to detect the proper card on boot you can
+ * override it by setting the following define to the card you are using:
+ *
+#define OVERRIDE_CARD <card type>
+ *
+ * where <card type> is one of the following card defines.
+ */
+#define CARD_UNKNOWN 0
+#define CARD_MIRO 1
+#define CARD_HAUPPAUGE 2
+#define CARD_STB 3
+#define CARD_INTEL 4
+#define CARD_IMS_TURBO 5
+#define CARD_AVER_MEDIA 6
+#define Bt848_MAX_CARD 7
+
+/*
+ * the data for each type of card
+ *
+ * Note:
+ * these entried MUST be kept in the order defined by the CARD_XXX defines!
+ */
+static const struct CARDTYPE cards[] = {
+
+ { CARD_UNKNOWN, /* the card id */
+ "Unknown", /* the 'name' */
+ NULL, /* the tuner */
+ 0, /* dbx unknown */
+ 0,
+ 0, /* EEProm unknown */
+ 0, /* EEProm unknown */
+ { 0, 0, 0, 0, 0 } },
+
+ { CARD_MIRO, /* the card id */
+ "Miro TV", /* the 'name' */
+ NULL, /* the tuner */
+ 0, /* dbx unknown */
+ 0,
+ 0, /* EEProm unknown */
+ 0, /* size unknown */
+ { 0x02, 0x01, 0x00, 0x0a, 1 } }, /* XXX ??? */
+
+ { CARD_HAUPPAUGE, /* the card id */
+ "Hauppauge WinCast/TV", /* the 'name' */
+ NULL, /* the tuner */
+ 0, /* dbx is optional */
+ 0,
+ PFC8582_WADDR, /* EEProm type */
+ (u_char)(256 / EEPROMBLOCKSIZE), /* 256 bytes */
+ { 0x00, 0x02, 0x01, 0x01, 1 } }, /* audio MUX values */
+
+ { CARD_STB, /* the card id */
+ "STB TV/PCI", /* the 'name' */
+ NULL, /* the tuner */
+ 0, /* dbx is optional */
+ 0,
+ X24C01_WADDR, /* EEProm type */
+ (u_char)(128 / EEPROMBLOCKSIZE), /* 128 bytes */
+ { 0x00, 0x01, 0x02, 0x02, 1 } }, /* audio MUX values */
+
+ { CARD_INTEL, /* the card id */
+ "Intel Smart Video III/VideoLogic Captivator PCI", /* the 'name' */
+ NULL, /* the tuner */
+ 0,
+ 0,
+ 0,
+ 0,
+ { 0, 0, 0, 0, 0 } },
+
+ { CARD_IMS_TURBO, /* the card id */
+ "IMS TV Turbo", /* the 'name' */
+ NULL, /* the tuner */
+ 0, /* dbx is optional */
+ 0,
+ PFC8582_WADDR, /* EEProm type */
+ (u_char)(256 / EEPROMBLOCKSIZE), /* 256 bytes */
+ { 0x01, 0x02, 0x01, 0x00, 1 } }, /* audio MUX values */
+
+ { CARD_AVER_MEDIA, /* the card id */
+ "AVer Media TV/FM", /* the 'name' */
+ NULL, /* the tuner */
+ 0, /* dbx is optional */
+ 0,
+ 0, /* EEProm type */
+ 0, /* EEProm size */
+ { 0x0c, 0x00, 0x0b, 0x0b, 1 } }, /* audio MUX values */
+};
+
+struct bt848_card_sig bt848_card_signature[1]= {
+ /* IMS TURBO TV : card 5 */
+ { 5,9, {00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 02, 00, 00, 00}}
+
+
+};
+
/* debug utility for holding previous INT_STAT contents */
#define STATUS_SUM
@@ -888,7 +1289,11 @@ bktr_probe( pcici_t tag, pcidi_t type )
case BROOKTREE_848_ID:
return("BrookTree 848");
case BROOKTREE_849_ID:
- return("BrookTree 849");
+ return("BrookTree 849");
+ case BROOKTREE_878_ID:
+ return("BrookTree 878");
+ case BROOKTREE_879_ID:
+ return("BrookTree 879");
};
return ((char *)0);
@@ -913,6 +1318,7 @@ bktr_attach( ATTACH_ARGS )
u_long latency;
u_long fun;
+
#ifdef __FreeBSD__
bktr = &brooktree[unit];
@@ -926,6 +1332,8 @@ bktr_attach( ATTACH_ARGS )
bktr->tag = tag;
pci_map_mem( tag, PCI_MAP_REG_START, (vm_offset_t *) &bktr->base,
&bktr->phys_base );
+ fun = pci_conf_read(tag, 0x40);
+ pci_conf_write(tag, 0x40, fun | 1);
#ifdef BROOKTREE_IRQ /* from the configuration file */
@@ -1117,11 +1525,22 @@ bktr_attach( ATTACH_ARGS )
buf = 0;
#endif
- DPR(("bktr%d: buffer size %d, addr 0x%x\n",
- unit, BROOKTREE_ALLOC, vtophys(buf)));
+ if ( bootverbose ) {
+ printf("bktr%d: buffer size %d, addr 0x%x\n",
+ unit, BROOKTREE_ALLOC, vtophys(buf));
+ }
bktr->bigbuf = buf;
bktr->alloc_pages = BROOKTREE_ALLOC_PAGES;
+
+#if defined(__OpenBSD__) || defined(__NetBSD__)
+ fun = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
+ pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, fun | 2);
+#else
+ fun = pci_conf_read(tag, PCI_COMMAND_STATUS_REG);
+ pci_conf_write(tag, PCI_COMMAND_STATUS_REG, fun | 2);
+#endif
+
if ( buf != 0 ) {
bzero((caddr_t) buf, BROOKTREE_ALLOC);
buf = vtophys(buf);
@@ -1139,6 +1558,17 @@ bktr_attach( ATTACH_ARGS )
bt848->gpio_dma_ctl = FIFO_RISC_DISABLED;
}
+ /* save pci id */
+#if defined(__OpenBSD__) || defined(__NetBSD__)
+ fun = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ID_REG);
+#else
+ fun = pci_conf_read(tag, PCI_ID_REG);
+#endif
+ bktr->id = fun;
+
+
+
+ bktr->clr_on_start = FALSE;
/* defaults for the tuner section of the card */
bktr->tflags = TUNER_INITALIZED;
bktr->tuner.frequency = 0;
@@ -1146,6 +1576,9 @@ bktr_attach( ATTACH_ARGS )
bktr->tuner.chnlset = DEFAULT_CHNLSET;
bktr->audio_mux_select = 0;
bktr->audio_mute_state = FALSE;
+ bktr->bt848_card = -1;
+ bktr->bt848_tuner = -1;
+ bktr->reverse_mute = -1;
probeCard( bktr, TRUE );
@@ -1221,9 +1654,9 @@ bktr_intr( void *arg )
status_sum |= (bktr_status & ~(BT848_INT_RSV0|BT848_INT_RSV1));
status_sum |= ((dstatus & (BT848_DSTATUS_COF|BT848_DSTATUS_LOF)) << 6);
#endif /* STATUS_SUM */
- /* printf( " STATUS %x %x %x \n",
+ /* printf( " STATUS %x %x %x \n",
dstatus, bktr_status, bt848->risc_count );
- */
+ */
/* if risc was disabled re-start process again */
if ( !(bktr_status & BT848_INT_RISC_EN) ||
((bktr_status &(BT848_INT_FBUS |
@@ -1466,6 +1899,35 @@ bktr_open( dev_t dev, int flags, int fmt, struct proc *p )
if (!(bktr->flags & METEOR_INITALIZED)) /* device not found */
return( ENXIO );
+ if (bt848_card != -1) {
+ if ((bt848_card >> 8 == unit ) &&
+ ( (bt848_card & 0xff) < Bt848_MAX_CARD )) {
+ if ( bktr->bt848_card != (bt848_card & 0xff) ) {
+ bktr->bt848_card = (bt848_card & 0xff);
+ probeCard(bktr, FALSE);
+ }
+ }
+ }
+
+ if (bt848_tuner != -1) {
+ if ((bt848_tuner >> 8 == unit ) &&
+ ( (bt848_tuner & 0xff) < Bt848_MAX_TUNER )) {
+ if ( bktr->bt848_tuner != (bt848_tuner & 0xff) ) {
+ bktr->bt848_tuner = (bt848_tuner & 0xff);
+ probeCard(bktr, FALSE);
+ }
+ }
+ }
+
+ if (bt848_reverse_mute != -1) {
+ if (((bt848_reverse_mute >> 8) == unit ) &&
+ ((bt848_reverse_mute & 0xff) < Bt848_MAX_TUNER) ) {
+ bktr->reverse_mute = bt848_reverse_mute & 0xff;
+ bt848_reverse_mute = -1;
+ }
+ }
+
+
switch ( MINOR( minor(dev) ) ) {
case VIDEO_DEV:
return( video_open( bktr ) );
@@ -1485,6 +1947,7 @@ static int
video_open( bktr_ptr_t bktr )
{
bt848_ptr_t bt848;
+ int frame_rate, video_format=0;
if (bktr->flags & METEOR_OPEN) /* device is busy */
return( EBUSY );
@@ -1497,23 +1960,59 @@ video_open( bktr_ptr_t bktr )
dump_bt848( bt848 );
#endif
+ bktr->clr_on_start = FALSE;
+
bt848->dstatus = 0x00; /* clear device status reg. */
bt848->adc = SYNC_LEVEL;
- bt848->iform = BT848_IFORM_M_MUX1 |
- BT848_IFORM_X_XT0 |
- BT848_IFORM_F_NTSCM;
+#if BROOKTREE_SYSTEM_DEFAULT == BROOKTREE_PAL
+ video_format = 0;
+#else
+ video_format = 1;
+#endif
+
+ if (bt848_format == 0 )
+ video_format = 0;
+
+ if (bt848_format == 1 )
+ video_format = 1;
+
+ if (video_format == 1 ) {
+ bt848->iform = BT848_IFORM_F_NTSCM;
+ bktr->format_params = BT848_IFORM_F_NTSCM;
+
+ } else {
+ bt848->iform = BT848_IFORM_F_PALBDGHI;
+ bktr->format_params = BT848_IFORM_F_PALBDGHI;
+
+ }
+
+ bt848->iform |= format_params[bktr->format_params].iform_xtsel;
+
+ /* work around for new Hauppauge 878 cards */
+ if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
+ (bktr->id==BROOKTREE_878_ID || bktr->id==BROOKTREE_879_ID) )
+ bt848->iform |= BT848_IFORM_M_MUX3;
+ else
+ bt848->iform |= BT848_IFORM_M_MUX1;
+
+ bt848->adelay = format_params[bktr->format_params].adelay;
+ bt848->bdelay = format_params[bktr->format_params].bdelay;
+ frame_rate = format_params[bktr->format_params].frame_rate;
+
+#ifdef BKTR_USE_PLL
+ bt848->tgctrl=0;
+ bt848->pll_f_lo=0xf9;
+ bt848->pll_f_hi=0xdc;
+ bt848->pll_f_xci=0x8e;
+#endif
+
bktr->flags = (bktr->flags & ~METEOR_DEV_MASK) | METEOR_DEV0;
- bktr->format_params = BT848_IFORM_F_NTSCM;
bktr->max_clip_node = 0;
-#ifndef ORIGINAL
bt848->color_ctl_gamma = 1;
-#else
- bt848->color_ctl_gamma = 0;
-#endif
bt848->color_ctl_rgb_ded = 1;
bt848->color_ctl_color_bars = 0;
bt848->color_ctl_ext_frmrate = 0;
@@ -1536,7 +2035,7 @@ video_open( bktr_ptr_t bktr )
bktr->even_fields_captured = 0;
bktr->odd_fields_captured = 0;
bktr->proc = (struct proc *)0;
- set_fps(bktr, 30);
+ set_fps(bktr, frame_rate);
bktr->video.addr = 0;
bktr->video.width = 0;
bktr->video.banksize = 0;
@@ -1545,12 +2044,11 @@ video_open( bktr_ptr_t bktr )
bktr->format = METEOR_GEO_RGB16;
bktr->pixfmt = oformat_meteor_to_bt( bktr->format );
+ bktr->capture_area_enabled = FALSE;
- bt848->int_mask = BT848_INT_MYSTERYBIT; /* what does this bit do ??? */
-
- /* wait 2 seconds while bt848 initialises */
- tsleep( (caddr_t)bktr, PZERO, "btinit", hz*2 );
-
+ bt848->int_mask = BT848_INT_MYSTERYBIT; /* if you take this out triton
+ based motherboards will
+ operate unreliably */
return( 0 );
}
@@ -1792,11 +2290,13 @@ video_ioctl( bktr_ptr_t bktr, int unit, int cmd, caddr_t arg, struct proc* pr )
struct meteor_counts *cnt;
#endif
struct meteor_video *video;
+ struct bktr_capture_area *cap_area;
vm_offset_t buf;
#if !defined(__NetBSD__) && !defined(__OpenBSD__)
struct format_params *fp;
int tmp_int;
#endif
+ char char_temp;
int i;
bt848 = bktr->base;
@@ -1869,7 +2369,7 @@ video_ioctl( bktr_ptr_t bktr, int unit, int cmd, caddr_t arg, struct proc* pr )
*(u_short *)arg = temp;
break;
- case BT848SFMT: /* set input format */
+ case BT848SFMT: /* set input format */
temp = *(unsigned long*)arg & BT848_IFORM_FORMAT;
temp_iform = bt848->iform;
temp_iform &= ~BT848_IFORM_FORMAT;
@@ -2023,7 +2523,9 @@ video_ioctl( bktr_ptr_t bktr, int unit, int cmd, caddr_t arg, struct proc* pr )
break;
case METEORSBRIG: /* set brightness */
- bt848->bright = *(u_char *)arg & 0xff;
+ char_temp = ( *(u_char *)arg & 0xff) - 128;
+ bt848->bright = char_temp;
+
break;
case METEORGBRIG: /* get brightness */
@@ -2073,6 +2575,14 @@ video_ioctl( bktr_ptr_t bktr, int unit, int cmd, caddr_t arg, struct proc* pr )
*(u_char *)arg = (u_char)((temp >> 1) & 0xff);
break;
+ case BT848SCBUF: /* set Clear-Buffer-on-start flag */
+ bktr->clr_on_start = (*(int *)arg != 0);
+ break;
+
+ case BT848GCBUF: /* get Clear-Buffer-on-start flag */
+ *(int *)arg = (int) bktr->clr_on_start;
+ break;
+
case METEORSSIGNAL:
if(*(int *)arg == 0 || *(int *)arg >= NSIG) {
return( EINVAL );
@@ -2318,6 +2828,55 @@ video_ioctl( bktr_ptr_t bktr, int unit, int cmd, caddr_t arg, struct proc* pr )
break;
/* end of METEORSETGEO */
+ /* FIXME. The Capture Area currently has the following restrictions:
+ GENERAL
+ y_offset may need to be even in interlaced modes
+ RGB24 - Interlaced mode
+ x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
+ y_size must be greater than or equal to METEORSETGEO height (rows)
+ RGB24 - Even Only (or Odd Only) mode
+ x_size must be greater than or equal to 1.666*METEORSETGEO width (cols)
+ y_size must be greater than or equal to 2*METEORSETGEO height (rows)
+ YUV12 - Interlaced mode
+ x_size must be greater than or equal to METEORSETGEO width (cols)
+ y_size must be greater than or equal to METEORSETGEO height (rows)
+ YUV12 - Even Only (or Odd Only) mode
+ x_size must be greater than or equal to METEORSETGEO width (cols)
+ y_size must be greater than or equal to 2*METEORSETGEO height (rows)
+ */
+
+ case BT848_SCAPAREA: /* set capture area of each video frame */
+ /* can't change parameters while capturing */
+ if (bktr->flags & METEOR_CAP_MASK)
+ return( EBUSY );
+
+ cap_area = (struct bktr_capture_area *) arg;
+ bktr->capture_area_x_offset = cap_area->x_offset;
+ bktr->capture_area_y_offset = cap_area->y_offset;
+ bktr->capture_area_x_size = cap_area->x_size;
+ bktr->capture_area_y_size = cap_area->y_size;
+ bktr->capture_area_enabled = TRUE;
+
+ bktr->dma_prog_loaded = FALSE;
+ break;
+
+ case BT848_GCAPAREA: /* get capture area of each video frame */
+ cap_area = (struct bktr_capture_area *) arg;
+ if (bktr->capture_area_enabled == FALSE) {
+ cap_area->x_offset = 0;
+ cap_area->y_offset = 0;
+ cap_area->x_size = format_params[
+ bktr->format_params].scaled_hactive;
+ cap_area->y_size = format_params[
+ bktr->format_params].vactive;
+ } else {
+ cap_area->x_offset = bktr->capture_area_x_offset;
+ cap_area->y_offset = bktr->capture_area_y_offset;
+ cap_area->x_size = bktr->capture_area_x_size;
+ cap_area->y_size = bktr->capture_area_y_size;
+ }
+ break;
+
default:
return common_ioctl( bktr, bt848, cmd, arg );
}
@@ -2687,15 +3246,32 @@ common_ioctl( bktr_ptr_t bktr, bt848_ptr_t bt848, int cmd, caddr_t arg )
switch (cmd) {
case METEORSINPUT: /* set input device */
+ /* Bt848 has 3 MUX Inputs. Bt848a/849/878/879 has 4 MUX Inputs*/
+ /* On the original bt848 boards, */
+ /* Tuner is MUX0, RCA is MUX1, S-Video is MUX2 */
+ /* On the Hauppauge bt878 boards, */
+ /* Tuner is MUX0, RCA is MUX4 */
+ /* Unfortunatly Meteor driver codes DEV_RCA as DEV_0, so we */
+ /* stick with this system in our Meteor Emulation */
+
switch(*(unsigned long *)arg & METEOR_DEV_MASK) {
/* this is the RCA video input */
case 0: /* default */
case METEOR_INPUT_DEV0:
- bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
- | METEOR_DEV0;
+ /* METEOR_INPUT_DEV_RCA: */
+ bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
+ | METEOR_DEV0;
bt848->iform &= ~BT848_IFORM_MUXSEL;
- bt848->iform |= BT848_IFORM_M_MUX1;
+
+ /* work around for new Hauppauge 878 cards */
+ if ((bktr->card.card_id == CARD_HAUPPAUGE) &&
+ (bktr->id==BROOKTREE_878_ID ||
+ bktr->id==BROOKTREE_879_ID) )
+ bt848->iform |= BT848_IFORM_M_MUX3;
+ else
+ bt848->iform |= BT848_IFORM_M_MUX1;
+
bt848->e_control &= ~BT848_E_CONTROL_COMP;
bt848->o_control &= ~BT848_O_CONTROL_COMP;
set_audio( bktr, AUDIO_EXTERN );
@@ -2724,6 +3300,22 @@ common_ioctl( bktr_ptr_t bktr, bt848_ptr_t bt848, int cmd, caddr_t arg )
set_audio( bktr, AUDIO_EXTERN );
break;
+ case METEOR_INPUT_DEV3:
+ /* how do I detect a bt848a ? */
+ if ((bktr->id == BROOKTREE_849_ID) ||
+ (bktr->id == BROOKTREE_878_ID) ||
+ (bktr->id == BROOKTREE_879_ID) ) {
+ bktr->flags = (bktr->flags & ~METEOR_DEV_MASK)
+ | METEOR_DEV3;
+ bt848->iform &= ~BT848_IFORM_MUXSEL;
+ bt848->iform |= BT848_IFORM_M_MUX3;
+ bt848->e_control &= ~BT848_E_CONTROL_COMP;
+ bt848->o_control &= ~BT848_O_CONTROL_COMP;
+ set_audio( bktr, AUDIO_EXTERN );
+
+ break;
+ }
+
default:
return( EINVAL );
}
@@ -2955,7 +3547,7 @@ static bool_t split(bktr_reg_t * bktr, volatile u_long **dma_prog, int width ,
/* must be Blue. */
start_skip = 0;
if (( pf->type == METEOR_PIXTYPE_RGB ) && ( pf->Bpp == 3 ))
- switch ( ((u_long) *target_buffer) % 4 ) {
+ switch ( ((uintptr_t) (void *) *target_buffer) % 4 ) {
case 2 : start_skip = 4 ; break;
case 1 : start_skip = 8 ; break;
}
@@ -2978,7 +3570,7 @@ static bool_t split(bktr_reg_t * bktr, volatile u_long **dma_prog, int width ,
*(*dma_prog)++ = operation | flag | (width * pixel_width - skip);
if (operation != OP_SKIP )
- *(*dma_prog)++ = (u_long) *target_buffer;
+ *(*dma_prog)++ = (uintptr_t) (void *) *target_buffer;
*target_buffer += width * pixel_width;
bktr->current_col += width;
@@ -3009,7 +3601,7 @@ static bool_t split(bktr_reg_t * bktr, volatile u_long **dma_prog, int width ,
*(*dma_prog)++ = operation | flag |
(width * pixel_width / 2 - skip);
if (operation != OP_SKIP )
- *(*dma_prog)++ = (u_long ) *target_buffer ;
+ *(*dma_prog)++ = (uintptr_t) (void *) *target_buffer ;
*target_buffer += (width * pixel_width / 2) ;
if ( operation == OP_WRITE )
@@ -3043,17 +3635,18 @@ rgb_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
bt848->vbi_pack_size = 0;
bt848->vbi_pack_del = 0;
bt848->adc = SYNC_LEVEL;
- bt848->color_ctl_rgb_ded = 1;
-#ifndef ORIGINAL
- bt848->color_ctl_gamma = 1;
- bt848->oform = 0;
- bt848->e_vscale_hi |= 0xc0;
- bt848->o_vscale_hi |= 0xc0;
-#else
- bt848->e_vscale_hi |= 0xc0;
- bt848->o_vscale_hi |= 0xc0;
-#endif
+ bt848->oform = 0x00;
+
+ bt848->e_vscale_hi |= 0x40; /* set chroma comb */
+ bt848->o_vscale_hi |= 0x40;
+ bt848->e_vscale_hi &= ~0x80; /* clear Ycomb */
+ bt848->o_vscale_hi &= ~0x80;
+
+ /* disable gamma correction removal */
+ bt848->color_ctl_gamma = 1;
+
+
if (cols > 385 ) {
bt848->e_vtc = 0;
bt848->o_vtc = 0;
@@ -3116,7 +3709,7 @@ rgb_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
switch (i_flag) {
case 1:
/* sync vre */
- *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE;
+ *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO;
*dma_prog++ = 0; /* NULL WORD */
*dma_prog++ = OP_JUMP;
@@ -3125,7 +3718,7 @@ rgb_prog( bktr_ptr_t bktr, char i_flag, int cols, int rows, int interlace )
case 2:
/* sync vro */
- *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRO;
+ *dma_prog++ = OP_SYNC | 1 << 24 | BKTR_VRE;
*dma_prog++ = 0; /* NULL WORD */
*dma_prog++ = OP_JUMP;
@@ -3449,21 +4042,7 @@ yuv12_prog( bktr_ptr_t bktr, char i_flag,
bktr->capcontrol = 1 << 6 | 1 << 4 | 3;
bt848->adc = SYNC_LEVEL;
- bt848->oform = 0x00;
-
- bt848->e_control |= BT848_E_CONTROL_LDEC; /* disable luma decimation */
- bt848->o_control |= BT848_O_CONTROL_LDEC;
-
- bt848->e_scloop |= BT848_O_SCLOOP_CAGC; /* chroma agc enable */
- bt848->o_scloop |= BT848_O_SCLOOP_CAGC;
-
- bt848->e_vscale_hi &= ~0x80; /* clear Ycomb */
- bt848->o_vscale_hi &= ~0x80;
- bt848->e_vscale_hi |= 0x40; /* set chroma comb */
- bt848->o_vscale_hi |= 0x40;
-
- /* disable gamma correction removal */
- bt848->color_ctl_gamma = 1;
+ bt848->oform = 0x0;
/* Construct Write */
inst = OP_WRITE123 | OP_SOL | OP_EOL | (cols);
@@ -3576,66 +4155,114 @@ build_dma_prog( bktr_ptr_t bktr, char i_flag )
bt848->gpio_dma_ctl &= ~FIFO_RISC_ENABLED;
/* set video parameters */
- temp = ((quad_t ) fp->htotal* (quad_t) fp->horizontal * 4096
- / fp->vertical / bktr->cols) - 4096;
+ if (bktr->capture_area_enabled)
+ temp = ((quad_t ) fp->htotal* (quad_t) bktr->capture_area_x_size * 4096
+ / fp->scaled_htotal / bktr->cols) - 4096;
+ else
+ temp = ((quad_t ) fp->htotal* (quad_t) fp->scaled_hactive * 4096
+ / fp->scaled_htotal / bktr->cols) - 4096;
+
+ /* printf("HSCALE value is %d\n",temp); */
bt848->e_hscale_lo = temp & 0xff;
bt848->o_hscale_lo = temp & 0xff;
bt848->e_hscale_hi = (temp >> 8) & 0xff;
bt848->o_hscale_hi = (temp >> 8) & 0xff;
-
+
/* horizontal active */
temp = bktr->cols;
+ /* printf("HACTIVE value is %d\n",temp); */
bt848->e_hactive_lo = temp & 0xff;
bt848->o_hactive_lo = temp & 0xff;
bt848->e_crop &= ~0x3;
bt848->o_crop &= ~0x3;
bt848->e_crop |= (temp >> 8) & 0x3;
bt848->o_crop |= (temp >> 8) & 0x3;
-
+
/* horizontal delay */
- temp = (fp->hdelay * bktr->cols) / fp->hactive;
+ if (bktr->capture_area_enabled)
+ temp = ( (fp->hdelay* fp->scaled_hactive + bktr->capture_area_x_offset* fp->scaled_htotal)
+ * bktr->cols) / (bktr->capture_area_x_size * fp->hactive);
+ else
+ temp = (fp->hdelay * bktr->cols) / fp->hactive;
+
temp = temp & 0x3fe;
+
+ /* printf("HDELAY value is %d\n",temp); */
bt848->e_delay_lo = temp & 0xff;
bt848->o_delay_lo = temp & 0xff;
bt848->e_crop &= ~0xc;
bt848->o_crop &= ~0xc;
bt848->e_crop |= (temp >> 6) & 0xc;
bt848->o_crop |= (temp >> 6) & 0xc;
-
+
/* vertical scale */
- if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
- bktr->flags & METEOR_ONLY_EVEN_FIELDS)
- tmp_int = 65536 -
+ if (bktr->capture_area_enabled) {
+ if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
+ bktr->flags & METEOR_ONLY_EVEN_FIELDS)
+ tmp_int = 65536 -
+ (((bktr->capture_area_y_size * 256 + (bktr->rows/2)) / bktr->rows) - 512);
+ else {
+ tmp_int = 65536 -
+ (((bktr->capture_area_y_size * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
+ }
+ } else {
+ if (bktr->flags & METEOR_ONLY_ODD_FIELDS ||
+ bktr->flags & METEOR_ONLY_EVEN_FIELDS)
+ tmp_int = 65536 -
(((fp->vactive * 256 + (bktr->rows/2)) / bktr->rows) - 512);
- else {
- tmp_int = 65536 -
+ else {
+ tmp_int = 65536 -
(((fp->vactive * 512 + (bktr->rows / 2)) / bktr->rows) - 512);
+ }
}
-
+
tmp_int &= 0x1fff;
+ /* printf("VSCALE value is %d\n",tmp_int); */
bt848->e_vscale_lo = tmp_int & 0xff;
bt848->o_vscale_lo = tmp_int & 0xff;
bt848->e_vscale_hi &= ~0x1f;
bt848->o_vscale_hi &= ~0x1f;
bt848->e_vscale_hi |= (tmp_int >> 8) & 0x1f;
bt848->o_vscale_hi |= (tmp_int >> 8) & 0x1f;
-
+
/* vertical active */
+ if (bktr->capture_area_enabled)
+ temp = bktr->capture_area_y_size;
+ else
+ temp = fp->vactive;
+ /* printf("VACTIVE is %d\n",temp); */
bt848->e_crop &= ~0x30;
- bt848->e_crop |= (fp->vactive >> 4) & 0x30;
- bt848->e_vactive_lo = fp->vactive & 0xff;
+ bt848->e_crop |= (temp >> 4) & 0x30;
+ bt848->e_vactive_lo = temp & 0xff;
bt848->o_crop &= ~0x30;
- bt848->o_crop |= (fp->vactive >> 4) & 0x30;
- bt848->o_vactive_lo = fp->vactive & 0xff;
-
+ bt848->o_crop |= (temp >> 4) & 0x30;
+ bt848->o_vactive_lo = temp & 0xff;
+
/* vertical delay */
- bt848->e_vdelay_lo = fp->vdelay;
- bt848->o_vdelay_lo = fp->vdelay;
+ if (bktr->capture_area_enabled)
+ temp = fp->vdelay + (bktr->capture_area_y_offset);
+ else
+ temp = fp->vdelay;
+ /* printf("VDELAY is %d\n",temp); */
+ bt848->e_crop &= ~0xC0;
+ bt848->e_crop |= (temp >> 2) & 0xC0;
+ bt848->e_vdelay_lo = temp & 0xff;
+ bt848->o_crop &= ~0xC0;
+ bt848->o_crop |= (temp >> 2) & 0xC0;
+ bt848->o_vdelay_lo = temp & 0xff;
/* end of video params */
+#ifdef BKTR_USE_PLL
+ if (fp->iform_xtsel==BT848_IFORM_X_XT1) {
+ bt848->tgctrl=8; /* Select PLL mode */
+ } else {
+ bt848->tgctrl=0; /* Select Normal xtal 0/xtal 1 mode */
+ }
+#endif
+
/* capture control */
switch (i_flag) {
case 1:
@@ -3710,6 +4337,13 @@ start_capture( bktr_ptr_t bktr, unsigned type )
fp = &format_params[bktr->format_params];
+ /* If requested, clear out capture buf first */
+ if (bktr->clr_on_start && (bktr->video.addr == 0)) {
+ bzero((caddr_t)bktr->bigbuf,
+ (size_t)bktr->rows * bktr->cols * bktr->frames *
+ pixfmt_table[ bktr->pixfmt ].public.Bpp);
+ }
+
bt848 = bktr->base;
bt848->dstatus = 0;
@@ -3981,11 +4615,17 @@ static int oformat_meteor_to_bt( u_long format )
/* */
#define I2CBITTIME (0x5<<4) /* 5 * 0.48uS */
+#define I2CBITTIME_878 (1 << 7)
#define I2C_READ 0x01
#define I2C_COMMAND (I2CBITTIME | \
BT848_DATA_CTL_I2CSCL | \
BT848_DATA_CTL_I2CSDA)
+#define I2C_COMMAND_878 (I2CBITTIME_878 | \
+ BT848_DATA_CTL_I2CSCL | \
+ BT848_DATA_CTL_I2CSDA)
+
+
/*
*
*/
@@ -4002,7 +4642,12 @@ i2cWrite( bktr_ptr_t bktr, int addr, int byte1, int byte2 )
bt848->int_stat = (BT848_INT_RACK | BT848_INT_I2CDONE);
/* build the command datum */
- data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND;
+ if (bktr->id == BROOKTREE_848_ID ||
+ bktr->id == BROOKTREE_849_ID) {
+ data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND;
+ } else {
+ data = ((addr & 0xff) << 24) | ((byte1 & 0xff) << 16) | I2C_COMMAND_878;
+ }
if ( byte2 != -1 ) {
data |= ((byte2 & 0xff) << 8);
data |= BT848_DATA_CTL_I2CW3B;
@@ -4041,7 +4686,14 @@ i2cRead( bktr_ptr_t bktr, int addr )
bt848->int_stat = (BT848_INT_RACK | BT848_INT_I2CDONE);
/* write the READ address */
- bt848->i2c_data_ctl = ((addr & 0xff) << 24) | I2C_COMMAND;
+ /* The Bt878 and Bt879 differed on the treatment of i2c commands */
+
+ if (bktr->id == BROOKTREE_848_ID ||
+ bktr->id == BROOKTREE_849_ID) {
+ bt848->i2c_data_ctl = ((addr & 0xff) << 24) | I2C_COMMAND;
+ } else {
+ bt848->i2c_data_ctl = ((addr & 0xff) << 24) | I2C_COMMAND_878;
+ }
/* wait for completion */
for ( x = 0x7fffffff; x; --x ) { /* safety valve */
@@ -4057,7 +4709,6 @@ i2cRead( bktr_ptr_t bktr, int addr )
return( (bt848->i2c_data_ctl >> 8) & 0xff );
}
-
#if defined( I2C_SOFTWARE_PROBE )
/*
@@ -4174,253 +4825,6 @@ readEEProm( bktr_ptr_t bktr, int offset, int count, u_char *data )
return( 0 );
}
-
-/******************************************************************************
- * card probe
- */
-
-
-/*
- * the recognized cards, used as indexes of several tables.
- *
- * if probeCard() fails to detect the proper card on boot you can
- * override it by setting the following define to the card you are using:
- *
-#define OVERRIDE_CARD <card type>
- *
- * where <card type> is one of the following card defines.
- */
-#define CARD_UNKNOWN 0
-#define CARD_MIRO 1
-#define CARD_HAUPPAUGE 2
-#define CARD_STB 3
-#define CARD_INTEL 4
-
-/*
- * the data for each type of card
- *
- * Note:
- * these entried MUST be kept in the order defined by the CARD_XXX defines!
- */
-static const struct CARDTYPE cards[] = {
-
- /* CARD_UNKNOWN */
- { "Unknown", /* the 'name' */
- NULL, /* the tuner */
- 0, /* dbx unknown */
- 0,
- 0, /* EEProm unknown */
- 0, /* EEProm unknown */
- { 0, 0, 0, 0, 0 } },
-
- /* CARD_MIRO */
- { "Miro TV", /* the 'name' */
- NULL, /* the tuner */
- 0, /* dbx unknown */
- 0,
- PFC8582_WADDR, /* EEProm type */
- (u_char)(256 / EEPROMBLOCKSIZE), /* 256bytes */
- { 0x02, 0x01, 0x00, 0x0a, 1 } }, /* XXX ??? */
-
- /* CARD_HAUPPAUGE */
- { "Hauppauge WinCast/TV", /* the 'name' */
- NULL, /* the tuner */
- 0, /* dbx is optional */
- 0,
- PFC8582_WADDR, /* EEProm type */
- (u_char)(256 / EEPROMBLOCKSIZE), /* 256 bytes */
- { 0x00, 0x02, 0x01, 0x01, 1 } }, /* audio MUX values */
-
- /* CARD_STB */
- { "STB TV/PCI", /* the 'name' */
- NULL, /* the tuner */
- 0, /* dbx is optional */
- 0,
- X24C01_WADDR, /* EEProm type */
- (u_char)(128 / EEPROMBLOCKSIZE), /* 128 bytes */
- { 0x00, 0x01, 0x02, 0x02, 1 } }, /* audio MUX values */
-
- /* CARD_INTEL */
- { "Intel Smart Video III/VideoLogic Captivator PCI", /* the 'name' */
- NULL, /* the tuner */
- 0,
- 0,
- 0,
- 0,
- { 0, 0, 0, 0, 0 } }
-};
-
-
-/*
- * the data for each type of tuner
- *
- * if probeCard() fails to detect the proper tuner on boot you can
- * override it by setting the following define to the tuner present:
- *
-#define OVERRIDE_TUNER <tuner type>
- *
- * where <tuner type> is one of the following tuner defines.
- */
-
-/* indexes into tuners[] */
-#define NO_TUNER 0
-#define TEMIC_NTSC 1
-#define TEMIC_PAL 2
-#define TEMIC_SECAM 3
-#define PHILIPS_NTSC 4
-#define PHILIPS_PAL 5
-#define PHILIPS_SECAM 6
-#define TEMIC_PALI 7
-#define PHILIPS_PALI 8
-#define PHILIPS_FR1236_NTSC 9
-#define PHILIPS_FR1216_PAL 10
-
-/* XXX FIXME: this list is incomplete */
-
-/* input types */
-#define TTYPE_XXX 0
-#define TTYPE_NTSC 1
-#define TTYPE_NTSC_J 2
-#define TTYPE_PAL 3
-#define TTYPE_PAL_M 4
-#define TTYPE_PAL_N 5
-#define TTYPE_SECAM 6
-
-/**
-struct TUNER {
- char* name;
- u_char type;
- u_char pllAddr;
- u_char pllControl;
- u_char bandLimits[ 2 ];
- u_char bandAddrs[ 3 ];
-};
- */
-static const struct TUNER tuners[] = {
-/* XXX FIXME: fill in the band-switch crosspoints */
- /* NO_TUNER */
- { "<none>", /* the 'name' */
- TTYPE_XXX, /* input type */
- 0x00, /* PLL write address */
- { 0x00, /* control byte for PLL */
- 0x00,
- 0x00,
- 0x00 },
- { 0x00, 0x00 }, /* band-switch crosspoints */
- { 0x00, 0x00, 0x00,0x00} }, /* the band-switch values */
-
- /* TEMIC_NTSC */
- { "Temic NTSC", /* the 'name' */
- TTYPE_NTSC, /* input type */
- TEMIC_NTSC_WADDR, /* PLL write address */
- { TSA552x_SCONTROL, /* control byte for PLL */
- TSA552x_SCONTROL,
- TSA552x_SCONTROL,
- 0x00 },
- { 0x00, 0x00 }, /* band-switch crosspoints */
- { 0x02, 0x04, 0x01, 0x00 } }, /* the band-switch values */
-
- /* TEMIC_PAL */
- { "Temic PAL", /* the 'name' */
- TTYPE_PAL, /* input type */
- TEMIC_PALI_WADDR, /* PLL write address */
- { TSA552x_SCONTROL, /* control byte for PLL */
- TSA552x_SCONTROL,
- TSA552x_SCONTROL,
- 0x00 },
- { 0x00, 0x00 }, /* band-switch crosspoints */
- { 0x02, 0x04, 0x01, 0x00 } }, /* the band-switch values */
-
- /* TEMIC_SECAM */
- { "Temic SECAM", /* the 'name' */
- TTYPE_SECAM, /* input type */
- 0x00, /* PLL write address */
- { TSA552x_SCONTROL, /* control byte for PLL */
- TSA552x_SCONTROL,
- TSA552x_SCONTROL,
- 0x00 },
- { 0x00, 0x00 }, /* band-switch crosspoints */
- { 0x02, 0x04, 0x01,0x00 } }, /* the band-switch values */
-
- /* PHILIPS_NTSC */
- { "Philips NTSC", /* the 'name' */
- TTYPE_NTSC, /* input type */
- PHILIPS_NTSC_WADDR, /* PLL write address */
- { TSA552x_SCONTROL, /* control byte for PLL */
- TSA552x_SCONTROL,
- TSA552x_SCONTROL,
- 0x00 },
- { 0x00, 0x00 }, /* band-switch crosspoints */
- { 0xa0, 0x90, 0x30, 0x00 } }, /* the band-switch values */
-
- /* PHILIPS_PAL */
- { "Philips PAL", /* the 'name' */
- TTYPE_PAL, /* input type */
- PHILIPS_PAL_WADDR, /* PLL write address */
- { TSA552x_FCONTROL, /* control byte for PLL */
- TSA552x_FCONTROL,
- TSA552x_FCONTROL,
- TSA552x_RADIO },
- { 0x00, 0x00 }, /* band-switch crosspoints */
- { 0xa0, 0x90, 0x30, 0xa4 } }, /* the band-switch values */
-
- /* PHILIPS_SECAM */
- { "Philips SECAM", /* the 'name' */
- TTYPE_SECAM, /* input type */
- 0x00, /* PLL write address */
- { TSA552x_SCONTROL, /* control byte for PLL */
- TSA552x_SCONTROL,
- TSA552x_SCONTROL,
- TSA552x_RADIO },
- { 0x00, 0x00 }, /* band-switch crosspoints */
- { 0xa0, 0x90, 0x30,0xa4 } }, /* the band-switch values */
-
- /* TEMIC_PAL I */
- { "Temic PAL I", /* the 'name' */
- TTYPE_PAL, /* input type */
- TEMIC_PALI_WADDR, /* PLL write address */
- { TSA552x_SCONTROL, /* control byte for PLL */
- TSA552x_SCONTROL,
- TSA552x_SCONTROL,
- 0x00 },
- { 0x00, 0x00 }, /* band-switch crosspoints */
- { 0x02, 0x04, 0x01,0x00 } }, /* the band-switch values */
-
- /* PHILIPS_PAL */
- { "Philips PAL I", /* the 'name' */
- TTYPE_PAL, /* input type */
- TEMIC_PALI_WADDR, /* PLL write address */
- { TSA552x_SCONTROL, /* control byte for PLL */
- TSA552x_SCONTROL,
- TSA552x_SCONTROL,
- 0x00 },
- { 0x00, 0x00 }, /* band-switch crosspoints */
- { 0xa0, 0x90, 0x30,0x00 } }, /* the band-switch values */
-
- /* PHILIPS_FR1236_NTSC */
- { "Philips FR1236 NTSC FM", /* the 'name' */
- TTYPE_NTSC, /* input type */
- PHILIPS_FR1236_NTSC_WADDR, /* PLL write address */
- { TSA552x_SCONTROL, /* control byte for PLL */
- TSA552x_SCONTROL,
- TSA552x_SCONTROL,
- 0x00},
- { 0x00, 0x00 }, /* band-switch crosspoints */
- { 0xa0, 0x90, 0x30,0x00 } }, /* the band-switch values */
-
- /* PHILIPS_FR1216_PAL */
- { "Philips FR1216 PAL FM", /* the 'name' */
- TTYPE_PAL, /* input type */
- PHILIPS_FR1216_PAL_WADDR, /* PLL write address */
- { TSA552x_FCONTROL, /* control byte for PLL */
- TSA552x_FCONTROL,
- TSA552x_FCONTROL,
- TSA552x_RADIO },
- { 0x00, 0x00 }, /* band-switch crosspoints */
- { 0xa0, 0x90, 0x30, 0xa4 } }, /* the band-switch values */
-};
-
-
/*
* get a signature of the card
* read all 128 possible i2c read addresses from 0x01 thru 0xff
@@ -4437,7 +4841,7 @@ signCard( bktr_ptr_t bktr, int offset, int count, u_char* sig )
for ( x = 0; x < 16; ++x )
sig[ x ] = 0;
- for ( x = 0; x < 128; ++x ) {
+ for ( x = 0; x < count; ++x ) {
if ( i2cRead( bktr, (2 * x) + 1 ) != ABSENT ) {
sig[ x / 8 ] |= (1 << (x % 8) );
}
@@ -4480,25 +4884,34 @@ static int check_for_i2c_devices( bktr_ptr_t bktr ){
* autodetection and i2c device checks.
*/
#define ABSENT (-1)
-
static void
probeCard( bktr_ptr_t bktr, int verbose )
{
- int card;
+ int card, i,j, card_found;
int status;
bt848_ptr_t bt848;
- int any_i2c_devices;
+ u_char probe_signature[128], *probe_temp;
+ int any_i2c_devices;
+ u_char probe_eeprom[128];
+ u_long tuner_code = 0;
- any_i2c_devices = check_for_i2c_devices( bktr );
+
+ any_i2c_devices = check_for_i2c_devices( bktr );
bt848 = bktr->base;
bt848->gpio_out_en = 0;
- DPR(("bktr: GPIO is 0x%08x\n", bt848->gpio_data));
+ if (bootverbose)
+ printf("bktr: GPIO is 0x%08x\n", bt848->gpio_data);
#if defined( OVERRIDE_CARD )
bktr->card = cards[ (card = OVERRIDE_CARD) ];
goto checkTuner;
#endif
+ if (bktr->bt848_card != -1 ) {
+ bktr->card = cards[ (card = bktr->bt848_card) ];
+ goto checkTuner;
+ }
+
/* Check for i2c devices */
if (!any_i2c_devices) {
@@ -4525,6 +4938,35 @@ probeCard( bktr_ptr_t bktr, int verbose )
goto checkTuner;
}
+ signCard( bktr, 1, 128, (u_char *) &probe_signature );
+
+ if (bootverbose) {
+ printf("card signature \n");
+ for (j = 0; j < Bt848_MAX_SIGN; j++) {
+ printf(" %02x ", probe_signature[j]);
+ }
+ printf("\n\n");
+ }
+ for (i = 0;
+ i < (sizeof bt848_card_signature)/ sizeof (struct bt848_card_sig);
+ i++ ) {
+
+ card_found = 1;
+ probe_temp = (u_char *) &bt848_card_signature[i].signature;
+
+ for (j = 0; j < Bt848_MAX_SIGN; j++) {
+ if ((probe_temp[j] & 0xf) != (probe_signature[j] & 0xf)) {
+ card_found = 0;
+ break;
+ }
+
+ }
+ if (card_found) {
+ bktr->card = cards[ card = bt848_card_signature[i].card];
+ bktr->card.tuner = &tuners[ bt848_card_signature[i].tuner];
+ goto checkDBX;
+ }
+ }
/* XXX FIXME: (how do I) look for a Miro card */
bktr->card = cards[ (card = CARD_MIRO) ];
@@ -4533,6 +4975,10 @@ checkTuner:
bktr->card.tuner = &tuners[ OVERRIDE_TUNER ];
goto checkDBX;
#endif
+ if (bktr->bt848_tuner != -1 ) {
+ bktr->card.tuner = &tuners[ bktr->bt848_tuner & 0xff ];
+ goto checkDBX;
+ }
/* Check for i2c devices */
if (!any_i2c_devices) {
@@ -4541,6 +4987,7 @@ checkTuner:
}
/* differentiate type of tuner */
+
switch (card) {
case CARD_MIRO:
switch (((bt848->gpio_data >> 10)-1)&7) {
@@ -4553,27 +5000,108 @@ checkTuner:
case 6: bktr->card.tuner = &tuners[ TEMIC_NTSC ]; break;
case 7: bktr->card.tuner = &tuners[ TEMIC_PALI ]; break;
}
+ goto checkDBX;
break;
- default:
- if ( i2cRead( bktr, TEMIC_NTSC_RADDR ) != ABSENT ) {
- bktr->card.tuner = &tuners[ TEMIC_NTSC ];
- goto checkDBX;
- }
- if ( i2cRead( bktr, PHILIPS_NTSC_RADDR ) != ABSENT ) {
- bktr->card.tuner = &tuners[ PHILIPS_NTSC ];
- goto checkDBX;
- }
+ case CARD_HAUPPAUGE:
+ /* The Hauppauge Windows driver gives the following Tuner Table */
+ /* To the right of this is the tuner models we select */
+ /*
+ 1 External
+ 2 Unspecified
+ 3 Phillips FI1216
+ 4 Phillips FI1216MF
+ 5 Phillips FI1236 PHILIPS_NTSC
+ 6 Phillips FI1246
+ 7 Phillips FI1256
+ 8 Phillips FI1216 MK2 PHILIPS_PALI
+ 9 Phillips FI1216MF MK2
+ a Phillips FI1236 MK2 PHILIPS_FR1236_NTSC
+ b Phillips FI1246 MK2 PHILIPS_PALI
+ c Phillips FI1256 MK2
+ d Temic 4032FY5
+ e Temic 4002FH5 TEMIC_PAL
+ f Temic 4062FY5 TEMIC_PALI
+ 10 Phillips FR1216 MK2
+ 11 Phillips FR1216MF MK2
+ 12 Phillips FR1236 MK2 PHILIPS_FR1236_NTSC
+ 13 Phillips FR1246 MK2
+ 14 Phillips FR1256 MK2
+ 15 Phillips FM1216 PHILIPS_FR1216_PAL
+ 16 Phillips FM1216MF
+ 17 Phillips FM1236 PHILIPS_FR1236_NTSC
+ */
- if ( card == CARD_HAUPPAUGE ) {
- if ( i2cRead( bktr, TEMIC_PALI_RADDR ) != ABSENT ) {
- bktr->card.tuner = &tuners[ TEMIC_PAL ];
- goto checkDBX;
- }
+ readEEProm(bktr, 0, 128, (u_char *) &probe_eeprom );
+
+ tuner_code = probe_eeprom[9];
+ switch (tuner_code) {
+
+ case 0x5:
+ bktr->card.tuner = &tuners[ PHILIPS_NTSC ];
+ goto checkDBX;
+
+ case 0x0a:
+ case 0x12:
+ case 0x17:
+ bktr->card.tuner = &tuners[ PHILIPS_FR1236_NTSC ];
+ goto checkDBX;
+
+ case 0x8:
+ case 0xb:
+ bktr->card.tuner = &tuners[ PHILIPS_PALI ];
+ goto checkDBX;
+
+ case 0xe:
+ bktr->card.tuner = &tuners[ TEMIC_PAL];
+ goto checkDBX;
+
+ case 0xf:
+ bktr->card.tuner = &tuners[ TEMIC_PALI ];
+ goto checkDBX;
+
+ case 0x15:
+ bktr->card.tuner = &tuners[ PHILIPS_FR1216_PAL];
+ goto checkDBX;
}
- /* no tuner found */
- bktr->card.tuner = &tuners[ NO_TUNER ];
- }
+ /* Unknown Tuner Byte */
+ break;
+
+ } /* end switch(card) */
+
+ /* At this point, a goto checkDBX has not occured */
+ /* We have not been able to select a Tuner */
+ /* We could simply go for No Tuner, but by some guesswork */
+ /* we can try and select a suitable tuner */
+
+
+ /* At address 0xc0/0xc1 is TEMIC NTSC and PHILIPS_FR1236_SECAM tuner*/
+ /* If we find a tuner at this address, assume it is TEMIC NTSC */
+ /* Sorry SECAM users */
+
+ if ( i2cRead( bktr, TEMIC_NTSC_RADDR ) != ABSENT ) {
+ bktr->card.tuner = &tuners[ TEMIC_NTSC ];
+ goto checkDBX;
+ }
+
+ /* At address 0xc6/0xc7 is the PHILIPS NTSC Tuner */
+ /* If we find a tuner at this address, assume it is PHILIPS NTSC */
+ /* PHILIPS NTSC Tuner is at address 0xc6 / 0xc7 */
+
+ if ( i2cRead( bktr, PHILIPS_NTSC_RADDR ) != ABSENT ) {
+ bktr->card.tuner = &tuners[ PHILIPS_NTSC ];
+ goto checkDBX;
+ }
+
+ /* At address 0xc2/0xc3 is the TEMIC_PALI, PHILIPS_PAL, */
+ /* PHILIPS_FR_NTSC and PHILIPS_FR_PAL Tuners */
+ /* and we cannot tell which is which. */
+ /* Default to No Tuner */
+
+
+ /* no tuner found */
+ bktr->card.tuner = &tuners[ NO_TUNER ];
+
checkDBX:
#if defined( OVERRIDE_DBX )
@@ -4605,7 +5133,7 @@ checkMSP:
checkEnd:
if ( verbose ) {
- printf( "%s: %s", bktr->bktr_dev.dv_xname, bktr->card.name);
+ printf( "%s", bktr->card.name );
if ( bktr->card.tuner )
printf( ", %s tuner", bktr->card.tuner->name );
if ( bktr->card.dbx )
@@ -4927,6 +5455,30 @@ static int jpncable[] = {
#undef IF_FREQ
#undef OFFSET
+/*
+ * xUSSR Broadcast Channels:
+ *
+ * 1: 49.75MHz - 2: 59.25MHz
+ * 3: 77.25MHz - 5: 93.25MHz
+ * 6: 175.25MHz - 12: 223.25MHz
+ * 13-20 - not exist
+ * 21: 471.25MHz - 34: 575.25MHz
+ * 35: 583.25MHz - 60: 775.25MHz
+ *
+ * IF freq: 38.90 MHz
+ */
+#define IF_FREQ 38.90
+static int xussr[] = {
+ 60, (int)(IF_FREQ * FREQFACTOR), 0,
+ 35, (int)(583.25 * FREQFACTOR), (int)(8.00 * FREQFACTOR),
+ 21, (int)(471.25 * FREQFACTOR), (int)(8.00 * FREQFACTOR),
+ 6, (int)(175.25 * FREQFACTOR), (int)(8.00 * FREQFACTOR),
+ 3, (int)( 77.25 * FREQFACTOR), (int)(8.00 * FREQFACTOR),
+ 1, (int)( 49.75 * FREQFACTOR), (int)(9.50 * FREQFACTOR),
+ 0
+};
+#undef IF_FREQ
+
static int* freqTable[] = {
NULL,
nabcst,
@@ -4934,7 +5486,8 @@ static int* freqTable[] = {
hrccable,
weurope,
jpnbcst,
- jpncable
+ jpncable,
+ xussr
};
@@ -5176,6 +5729,12 @@ set_audio( bktr_ptr_t bktr, int cmd )
#else
bktr->audio_mux_select = 0;
#endif
+
+ if (bktr->reverse_mute )
+ bktr->audio_mux_select = 0;
+ else
+ bktr->audio_mux_select = 3;
+
break;
case AUDIO_EXTERN:
bktr->audio_mux_select = 1;
@@ -5205,12 +5764,19 @@ set_audio( bktr_ptr_t bktr, int cmd )
/* XXX FIXME: this was an 8 bit reference before new struct ??? */
bt848->gpio_reg_inp = (~GPIO_AUDIOMUX_BITS & 0xff);
- if ( bktr->audio_mute_state == TRUE )
+ if ( bktr->audio_mute_state == TRUE ) {
#ifdef BKTR_REVERSEMUTE
idx = 0;
#else
idx = 3;
#endif
+
+ if (bktr->reverse_mute )
+ idx = 3;
+ else
+ idx = 0;
+
+ }
else
idx = bktr->audio_mux_select;
@@ -5218,7 +5784,7 @@ set_audio( bktr_ptr_t bktr, int cmd )
bt848->gpio_data =
#if defined( AUDIOMUX_DISCOVER )
bt848->gpio_data = temp | (cmd & 0xff);
- printf("cmd: %d\n", cmd );
+ printf("cmd: %d audio mux %x temp %x \n", cmd,bktr->card.audiomuxs[ idx ], temp );
#else
temp | bktr->card.audiomuxs[ idx ];
#endif /* AUDIOMUX_DISCOVER */